URAL-1982-Electrification Plan最小生成樹或並查集
阿新 • • 發佈:2018-02-13
ural 理解 生成 color algo 大小 span 不用 一個個
Electrification Plan
題意:在一個無向圖中,給你幾個源點,找出把所有點連接到源點後最小的消費;
可以利用並查集:
先用結構體把每個邊存起來,再按照消費大小排序。之後從消費小的到大的一個個嘗試,兩個點需要連接的話,連接上同時把消費也算上去;
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <string> const int inf = 0x3f3f3f; using namespacestd; int n,k; int fa[10000+7]; struct node { int from,to; int c; }a[10007]; bool cmp(node a,node b) { return a.c<b.c; } void init(){ for(int i=1;i<=n;i++) fa[i] = i; } int find(int x) { if(fa[x]==x)return x; else return fa[x] = find(fa[x]); } int uni(int x,int y) {if(fa[x]==-1&&fa[y]==-1)return 0; //(**) int px = find(x); int py = find(y); if(px==py)return 0; else { fa[px] = py; return 1; } } int main(){ scanf("%d%d",&n,&k); init(); for(int i=1;i<=k;i++) { int x; scanf("%d",&x); fa[x]=-1; //這個操作我其實不是很明確,我以我的理解加上了(**)這句, } //表示源點之間不用連接,但是別人寫的好像不用加這句話。 int cnt =0; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { int cost; scanf("%d",&cost); if(cost==0)continue; a[++cnt].c=cost; a[cnt].from = i; a[cnt].to =j; } } sort(a+1,a+1+cnt,cmp); int ans = 0; for(int i=1;i<=cnt;i++) { if(uni(a[i].from,a[i].to)) { ans += a[i].c; } } printf("%d\n",ans); return 0; }
我自己就做了一個預處理,(直接把讀入的用uni連接起來
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <string> const int inf = 0x3f3f3f; using namespace std; int n,k; int fa[10000+7]; struct node { int from,to; int c; }a[10007]; bool cmp(node a,node b) { return a.c<b.c; } void init(){ for(int i=1;i<=n;i++) fa[i] = i; } int find(int x) { if(fa[x]==x)return x; else return fa[x] = find(fa[x]); } int uni(int x,int y) { int px = find(x); int py = find(y); if(px==py)return 0; else { fa[px] = py; return 1; } } int main(){ scanf("%d%d",&n,&k); init(); int last=-1; for(int i=1;i<=k;i++) { int x; scanf("%d",&x); if(last!=-1) { int suibian; suibian =uni(last,x); //不理解別人把fa[x]=-1的操作; last = x; //自己就先預處理連接好了; } else last=x; } int cnt =0; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { int cost; scanf("%d",&cost); if(cost==0)continue; a[++cnt].c=cost; a[cnt].from = i; a[cnt].to =j; } } sort(a+1,a+1+cnt,cmp); int ans = 0; for(int i=1;i<=cnt;i++) { if(uni(a[i].from,a[i].to)) { ans += a[i].c; } } printf("%d\n",ans); return 0; }
URAL-1982-Electrification Plan最小生成樹或並查集