题意,在给出的图中,使用最小花费的边,使这个图仍然连通。
#include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int maxn=10005; int head[maxn]; int n,len=0,counter; long long ans; struct node{ int v,cost,u; //操作符的重写默认是小于等于 bool operator < (const node& tmp) const{ return cost< tmp.cost; } }gra[maxn]; struct BingCha{ //并查集 int father[105]; void initial(){ //初始化不要忘记 for(int i=1;i<=n;i++){ father[i]=i; } } int getfather(int v){ if(father[v]==v)return v; return father[v]=getfather(father[v]); //状态压缩 } bool findtwo(int a,int b){ //看是否是同根的 return getfather(a)==getfather(b); } void unioned(int a,int b){ int fa=father[a],fb=father[b]; father[fa]=fb; } }jihe; void addedge(int u,int v,int cost){ gra[len].u=u; gra[len].v=v; gra[len].cost=cost; len++; } void init(){ len=0; counter=1;ans=0; int x; memset(head,-1,sizeof(head)); //memset gra? for(int i=1;i<=n;i++){//add the edges for(int j=1;j<=n;j++){ scanf("%d",&x); if(i<j){ addedge(i,j,x); } } } } int main(){ while(scanf("%d",&n)!=EOF){ init(); sort(gra,gra+len); //已经有序,那么从小值开始选边添加即可,也保证了最优结果 int idx=0; jihe.initial(); while(counter<n || idx<len){ if(!jihe.findtwo(gra[idx].u,gra[idx].v)){ //如果不同根,就选择这条边,执行更新操作 ans+=gra[idx].cost; counter++; jihe.unioned(gra[idx].u,gra[idx].v); } idx++; } printf("%d\n",ans); } }
2421 也是裸的mst:只要把已经建了的作为输入先处理一下就好了。
1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 using namespace std; 5 const int maxn=10010; 6 7 int n,len,counter; 8 long long ans; 9 struct node{ 10 int v,cost,u; 11 bool operator < (const node& tmp) const{ 12 return cost< tmp.cost; 13 14 } 15 }gra[maxn*(maxn-1)>>1]; 16 struct BingCha{ 17 int father[110]; 18 void initial(){ 19 for(int i=0;i<=n;i++){ 20 father[i]=i; 21 } 22 } 23 int getfather(int v){ 24 if(father[v]==v)return v; 25 return father[v]=getfather(father[v]); 26 } 27 bool findtwo(int a,int b){ 28 return getfather(a)==getfather(b); 29 } 30 void unioned(int a,int b){ 31 int fa=getfather(a),fb=getfather(b); 32 father[fa]=fb; 33 } 34 }jihe; 35 void addedge(int u,int v,int cost){ 36 gra[len].u=u; 37 gra[len].v=v; 38 gra[len].cost=cost; 39 len++; 40 } 41 int findxy(int x,int y){ 42 43 if(x>y){int z=y;y=x;x=z;} 44 int j=n-1,id=0; 45 for(int i=1;i<x;i++){ 46 id+=j--; 47 } 48 y-=x;// here!!! 49 id+=y; 50 return id; 51 } 52 void init(){ 53 len=0; 54 counter=1;ans=0; 55 jihe.initial(); 56 int x,q,y; 57 //memset gra? 58 for(int i=1;i<=n;i++){//add the edges 59 for(int j=1;j<=n;j++){ 60 scanf("%d",&x); 61 if(i<j){ 62 addedge(i,j,x); 63 } 64 } 65 } 66 scanf("%d",&q); 67 for(int i=1;i<=q;i++){ 68 scanf("%d%d",&x,&y); 69 int idx=findxy(x,y)-1; 70 if(!jihe.findtwo(gra[idx].u,gra[idx].v)){ 71 counter++; 72 jihe.unioned(gra[idx].u,gra[idx].v); 73 } 74 } 75 } 76 77 78 int main(){ 79 while(scanf("%d",&n)!=EOF){ 80 init(); 81 sort(gra,gra+len); 82 int idx=0; 83 while(counter<n){//|| idx<=len 84 if(!jihe.findtwo(gra[idx].u,gra[idx].v)){ 85 ans+=gra[idx].cost; 86 counter++; 87 jihe.unioned(gra[idx].u,gra[idx].v); 88 } 89 idx++; 90 } 91 printf("%d\n",ans); 92 93 } 94 }