1.理解题意后可以发现要求的图是任意两点间存在至少两条不相同的路径,这里自己犯了个错误,误以为只要简单的两两匹配度数为1的点既能得到答案,这种想法错误的原因在于:可能存在一点度数>1但与它对应的边存在桥边.
虽然想简单了,但是可以立即发现,问题的关键在于桥边(其实题意要求的就是双连通分量)
2.用tarjan求桥边,桥边性质:存在(u,v)两点u->v,并且DFN(u)<LOW[v];
3.其它的就只剩缩点和求缩点后度数为1的结点数目了,,这里有个小技巧是:由于删除桥边后图中的点被分割成一块一块的连通分量,所以只要一个dfs()既能给所有点打上标签了
#include <iostream> #include <queue> #include <string> #include <map> #include <vector> #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> using namespace std; const int MAX=10000*2+5,MAXN=5005,INF=1<<30; int F,R; bool vis[MAX]; int u[MAX],v[MAX],next[MAX]; int first[MAXN]; int l; int index; int DFN[MAXN],LOW[MAXN]; int cnt; int belong[MAXN]; struct Edge{ int u,v; }; Edge E[MAX]; int degree[MAXN]; void tarjan(int i){ int j; DFN[i]=LOW[i]=++index; for(int e=first[i];e!=-1;e=next[e]){ if(vis[e]) continue; vis[e]=vis[e^1]=1; j=v[e]; if(!DFN[j]){ tarjan(j); LOW[i]=min(LOW[i],LOW[j]); } else LOW[i]=DFN[j]; } } void color(int i){ int j; for(int e=first[i];e!=-1;e=next[e]){ j=v[e]; if(vis[e]) continue; if(!DFN[j]){ DFN[j]=1; belong[j]=cnt; color(j); } } } int main() { #ifndef ONLINE_JUDGE freopen("i.txt", "r", stdin); #endif int v1,v2; int leaf; memset(first,-1,sizeof(first)); l=0; scanf("%d %d/n",&F,&R); for(int i=0;i<R;i++){ scanf("%d %d/n",&v1,&v2); u[l]=v1; v[l]=v2; next[l]=first[v1]; first[v1]=l++; u[l]=v2; v[l]=v1; next[l]=first[v2]; first[v2]=l++; } index=cnt=0; tarjan(1);//题意说明两天之间至少有一条无向边 memset(vis,0,sizeof(vis)); for(int i=1,j;i<=F;i++){ for(int e=first[i];e!=-1;e=next[e]){ j=v[e]; if(DFN[i]<LOW[j]){ vis[e]=vis[e^1]=1; } } } cnt=0; memset(DFN,0,sizeof(DFN)); for(int i=1;i<=F;i++){ if(!DFN[i]){ ++cnt; DFN[i]=1; belong[i]=cnt; color(i); } } l=0; memset(vis,0,sizeof(vis)); for(int i=1,j;i<=F;i++){ for(int e=first[i];e!=-1;e=next[e]){ if(vis[e]) continue; vis[e]=vis[e^1]=1; j=v[e]; if(belong[i]!=belong[j]){ E[l].u=belong[i]; E[l++].v=belong[j]; } } } for(int e=0;e<l;e++){ ++degree[E[e].u]; ++degree[E[e].v]; } leaf=0; for(int i=1;i<=cnt;i++){ if(degree[i]==1) ++leaf; } printf("%d/n",(int)ceil((double)leaf/2)); return 0; }