Day4-T4
Describe:建个图,连通后删边 [ 如果把 !dis[i][j] 全部定义为INF会更好理解 ] 。先特判,再贪心求总数
code:
#pragma GCC optimize(2) #include<bits/stdc++.h> using namespace std; int n,m,k,tot,nn,ans,t; int father[5005],fa[5005]; bool b[5050]; struct bian{ long long l,r,w; }dis[100010]; bool cmp(bian x,bian y){return x.w<y.w;} int getfather(int p){ if(father[p]==p) return p; return father[p]=getfather(father[p]); } void uni(int x,int y){ int fx=getfather(x); int fy=getfather(y); if(fx!=fy) father[fx]=fy; } int getfa(int p){ if(fa[p]==p) return p; return fa[p]=getfa(fa[p]); } void Uni(int x,int y){ int fx=getfa(x); int fy=getfa(y); if(fx!=fy) fa[fx]=fy; } inline long long read(){ long long ret=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9') {if (ch=='-') f=-f;ch=getchar();} while (ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar(); return ret*f; } inline void write(int x){ if(x<0){putchar('-');write(-x);return;} if(x/10) write(x/10); putchar(x%10+'0'); } int main(){ //freopen("pocket.in","r",stdin); //freopen("pocket.out","w",stdout); t=read(); while(t--){ memset(dis,0,sizeof(dis)); memset(b,0,sizeof(b)); n=0,m=0,k=0,tot=0,nn=0,ans=0; n=read(),m=read(),k=read(); for(int i=1;i<=n;i++)father[i]=i,fa[i]=i; for(int i=1;i<=m;i++)dis[i].l=read(),dis[i].r=read(),dis[i].w=read(),Uni(dis[i].l,dis[i].r); for(int i=1;i<=n;i++){ //此段代码判断是否可能满足条件 int ss=getfa(i); if(!b[ss])b[ss]++,tot++; } if(tot>k||n<k){cout<<"No Answer"<<endl;continue;} //云数小于棉花糖数或全合并后依旧比限制多 sort(dis+1,dis+m+1,cmp); //按边权排序 for(int i=1;i<=m;i++){ //Kruskal int sum=0; if(getfather(dis[i].l)!=getfather(dis[i].r)){ uni(dis[i].l,dis[i].r); ans+=dis[i].w;nn++; } if(nn==n-k)break; //只需要n-k条边 } write(ans); puts(""); } return 0; }