Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4439 Accepted Submission(s): 1298
1 #include <iostream> 2 #include <iomanip> 3 #include <fstream> 4 #include <sstream> 5 #include <algorithm> 6 #include <string> 7 #include <set> 8 #include <utility> 9 #include <queue> 10 #include <stack> 11 #include <list> 12 #include <vector> 13 #include <cstdio> 14 #include <cstdlib> 15 #include <cstring> 16 #include <cmath> 17 #include <ctime> 18 #include <ctype.h> 19 using namespace std; 20 const int N=1000000; 21 int Tc,n,m,k,done,ans; 22 int father[N]; 23 int num[N]; 24 25 int findset(int p){ 26 if (father[p]==p) 27 return p; 28 father[p]=findset(father[p]); 29 return father[p]; 30 } 31 32 typedef struct edge 33 { 34 int x,y; 35 int len; 36 }Edge; 37 Edge edge[N]; 38 39 int cmp(const Edge &a,const Edge &b){ 40 return a.len<b.len; 41 } 42 43 void kruskal(){ 44 if (done==n-1) return; 45 sort(edge+1,edge+m+1,cmp); 46 for (int i=1;i<=m;i++){ 47 int x=edge[i].x,y=edge[i].y; 48 if (findset(x)!=findset(y)){ 49 if (num[father[x]]<num[father[y]]){ 50 num[father[y]]+=num[father[x]]; 51 father[father[x]]=father[y]; 52 } 53 else{ 54 num[father[x]]+=num[father[y]]; 55 father[father[y]]=father[x]; 56 } 57 done++; 58 ans+=edge[i].len; 59 if (done==n-1) return; 60 } 61 } 62 } 63 64 int main(){ 65 scanf("%d",&Tc); 66 for (int q=1;q<=Tc;q++) 67 { 68 done=0; ans=0; 69 int i,j,t,one,x; 70 scanf("%d%d%d",&n,&m,&k); 71 for (i=1;i<=n;i++){ 72 father[i]=i; 73 num[i]=1; 74 } 75 for (i=1;i<=m;i++) 76 scanf("%d%d%d",&edge[i].x,&edge[i].y,&edge[i].len); 77 for (i=1;i<=k;i++){ 78 scanf("%d%d",&t,&one); 79 for (j=1;j<t;j++){ 80 scanf("%d",&x); 81 if (findset(x)!=findset(one)){ 82 if (num[father[x]]<num[father[one]]){ 83 num[father[one]]+=num[father[x]]; 84 father[father[x]]=father[one]; 85 } 86 else{ 87 num[father[x]]+=num[father[one]]; 88 father[father[one]]=father[x]; 89 } 90 done++; 91 } 92 } 93 } 94 kruskal(); 95 if (done==n-1) printf("%d\n",ans); 96 else printf("-1\n"); 97 } 98 }
还可以水过去
code:
1 #include<iostream> 2 #include<algorithm> 3 using namespace std; 4 int f[505],L[505]; 5 struct node 6 { 7 int x,y,s; 8 }dd[25005]; 9 bool cmp(node a,node b) 10 { 11 return a.s<b.s; 12 } 13 int find(int a) 14 { 15 if(a!=f[a]) 16 a=find(f[f[a]]); 17 return a; 18 } 19 void Union(int x,int y) 20 { 21 if(x>y) 22 f[x]=y; 23 else 24 f[y]=x; 25 } 26 int main() 27 { 28 int n,m,k,t; 29 int i,j; 30 int T; 31 scanf("%d",&T); 32 while(T--) 33 { 34 scanf("%d%d%d",&n,&m,&k); 35 for(i=0;i<m;i++) 36 scanf("%d %d %d",&dd[i].x,&dd[i].y,&dd[i].s); 37 sort(dd,dd+m,cmp); 38 for(i=1;i<=n;i++) 39 f[i]=i; 40 int One,Two; 41 for(i=0;i<k;i++) 42 { 43 scanf("%d%d",&t,&One); 44 for(j=1;j<t;j++) 45 { 46 scanf("%d",&Two); 47 int xx=find(One); 48 int yy=find(Two); 49 if(xx!=yy) 50 Union(xx,yy); 51 } 52 } 53 int sum=0; 54 for(i=0;i<m;i++) 55 { 56 int xx=find(dd[i].x); 57 int yy=find(dd[i].y); 58 if(xx!=yy) 59 { 60 Union(xx,yy); 61 sum+=dd[i].s; 62 } 63 } 64 int cnt=0; 65 for(i=1;i<=n;i++) 66 if(i==f[i]) 67 cnt++; 68 if(cnt>1) 69 printf("-1\n"); 70 else 71 printf("%d\n",sum); 72 } 73 return 0; 74 }
以树的数量进行记录
code:
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 struct node 5 { 6 int x,y,z; 7 }arr[25100]; 8 int n,m,k,t,a[510],pre[510],cnt; 9 bool v[510]; 10 int cmp(const void *p,const void *q) 11 { 12 return ((node *)p)->z-((node *)q)->z; 13 } 14 int find(int x) 15 { 16 while(x!=pre[x]) 17 x=pre[x]; 18 return x; 19 } 20 void bcj() 21 { 22 int ans=0,flag=0,cat=0; 23 bool vit[510],v[510]; 24 for(int i=1;i<=n;i++) 25 vit[i]=false; 26 for(int i=0;i<m;i++) 27 { 28 int fx=find(arr[i].x); 29 int fy=find(arr[i].y); 30 if(fx!=fy) 31 { 32 pre[fx]=fy; 33 cat++; 34 ans+=arr[i].z; 35 } 36 if(cat==cnt-1) 37 break; 38 } 39 for(int j=1;j<=n;j++) 40 vit[find(j)]=true; 41 for(int j=1;j<=n;j++) 42 { 43 if(vit[j]) 44 { 45 flag++; 46 vit[j]=false; 47 } 48 } 49 if(flag==1) 50 { 51 printf("%d\n",ans); 52 return; 53 } 54 else 55 { 56 printf("-1\n"); 57 return; 58 } 59 } 60 int main() 61 { 62 int p; 63 while(~scanf("%d",&p)) 64 { 65 while(p--) 66 { 67 cnt=0; 68 scanf("%d%d%d",&n,&m,&k); 69 for(int i=1;i<=n;i++) 70 { 71 pre[i]=i;v[i]=false; 72 } 73 for(int i=0;i<m;i++) 74 scanf("%d%d%d",&arr[i].x,&arr[i].y,&arr[i].z); 75 qsort(arr,m,sizeof(arr[0]),cmp); 76 for(int i=0;i<k;i++) 77 { 78 scanf("%d",&t); 79 for(int j=1;j<=t;j++) 80 scanf("%d",&a[j]); 81 for(int j=1;j<t;j++) 82 { 83 int fx=find(a[j]); 84 int fy=find(a[j+1]); 85 if(fx!=fy) 86 pre[fx]=fy; 87 } 88 } 89 for(int i=1;i<=n;i++) 90 { 91 int fx=find(i); 92 if(!v[fx]) 93 { 94 v[fx]=true; 95 cnt++; 96 } 97 } 98 //printf("cnt=%d\n",cnt); 99 bcj(); 100 } 101 } 102 return 0; 103 }
注意:
刚开始的时候,findset()这个函数一直是不对,以后要改过来!
正确写法:
1 int findset(int p){ 2 if (father[p]==p) 3 return p; 4 father[p]=findset(father[p]); 5 return father[p]; 6 }