标签:
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 118 Accepted Submission(s): 52
题意:给出一张 n 个点 n+1 条边的无向图,你可以选择一些边(至少一条)删除。有多少种方案使得删除之后图依然联通。
这是best coder上面比赛的题目,可我比赛时数组开小了!!!!!
内心哔了狗有木有!!!!!!!!!!!!!!!!!!!!!
这里我用了组合数学,0ms过(其实暴力N³也可以过)~~~
第一名哦!!!
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 const int maxn=110; 6 int edge[maxn][3]; 7 int fa[maxn],cnt=1,fir[maxn],nxt[maxn<<1],to[maxn<<1]; 8 int dep[maxn],pre[maxn],ret[maxn],ID[maxn<<1]; 9 int find(int x) 10 { 11 return fa[x]==x?x:fa[x]=find(fa[x]); 12 } 13 14 void addedge(int a,int b,int id) 15 { 16 nxt[++cnt]=fir[a];ID[cnt]=id; 17 to[cnt]=b;fir[a]=cnt; 18 } 19 20 void DFS(int node) 21 { 22 for(int i=fir[node];i;i=nxt[i]) 23 { 24 if(dep[to[i]])continue; 25 dep[to[i]]=dep[node]+1; 26 pre[to[i]]=i; 27 DFS(to[i]); 28 } 29 } 30 int Search(int x,int y,int d) 31 { 32 while(x!=y){ 33 if(dep[x]<dep[y]) 34 swap(x,y); 35 ret[ID[pre[x]]]+=d; 36 x=to[pre[x]^1]; 37 } 38 } 39 void Init() 40 { 41 memset(fir,0,sizeof(fir)); 42 memset(ret,0,sizeof(ret)); 43 cnt=1; 44 } 45 46 int main() 47 { 48 freopen("data.in","r",stdin); 49 freopen("wrong.out","w",stdout); 50 int T,n; 51 scanf("%d",&T); 52 while(T--) 53 { 54 Init(); 55 scanf("%d",&n); 56 for(int i=1;i<=n+1;i++){ 57 fa[i]=i; 58 } 59 60 for(int i=1;i<=n+1;i++) 61 scanf("%d%d",&edge[i][0],&edge[i][1]); 62 for(int i=1;i<=n+1;i++){ 63 int a=find(edge[i][0]),b=find(edge[i][1]); 64 if(a==b) 65 edge[i][2]=1; 66 else{ 67 fa[a]=b; 68 addedge(edge[i][0],edge[i][1],i); 69 addedge(edge[i][1],edge[i][0],i); 70 } 71 } 72 int flag=0; 73 for(int i=2;i<=n;i++) 74 if(find(i)!=find(i-1)){ 75 printf("0\n"); 76 flag=1; 77 break; 78 } 79 if(flag==1)continue; 80 dep[1]=1; 81 DFS(1); 82 int ans=0,a=0,b=0,c=0; 83 for(int i=1;i<=n+1;i++){ 84 if(edge[i][2]){ 85 if(!ans){ 86 Search(edge[i][0],edge[i][1],1); 87 ret[i]+=1; 88 } 89 90 else { 91 Search(edge[i][0],edge[i][1],10); 92 ret[i]+=10; 93 } 94 ans+=1; 95 } 96 } 97 for(int i=1;i<=n+1;i++){ 98 if(ret[i]==1)a++; 99 else if(ret[i]==10)b++; 100 else if(ret[i]==11)c++,b++,a++; 101 } 102 printf("%d\n",a+b-c+(a+b-c-1)*(a+b-c)/2-(a-c)*(a-c-1)/2-(b-c)*(b-c-1)/2-c*(c-1)/2); 103 } 104 return 0; 105 }
图论(生成树):HDU 5631Rikka with Graph
标签:
原文地址:http://www.cnblogs.com/TenderRun/p/5204192.html