3624: [Apio2008]免费道路
Time Limit: 2 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 1709 Solved: 694
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
5 7 2
1 3 0
4 5 1
3 2 0
5 3 1
4 3 0
1 2 1
4 2 1
1 3 0
4 5 1
3 2 0
5 3 1
4 3 0
1 2 1
4 2 1
Sample Output
3 2 0
4 3 0
5 3 1
4 3 0
5 3 1
模拟+并查集
最后如果有解的话,那么所有的道路会构成一棵树
首先确定哪些鹅卵石路必须选,然后判断是否大于k,如果大于则是no solution
然后包含必须选的鹅卵石路选择k条,最后确定水泥路
还有如果鹅卵石路本来就小于k的话也是no solution
#include <bits/stdc++.h>
#define ll long long
#define inf 100000000
using namespace std;
inline int read(){
int x=0;int f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
return x*f;
}
const int MAXN=1e6+10;
int f[MAXN];
int u[MAXN],v[MAXN],c[MAXN],n,m,au[MAXN],ac[MAXN],num[3],av[MAXN],top,ans,vis[MAXN];
inline int find(int xx){
return xx==f[xx]?xx:f[xx]=find(f[xx]);
}
inline void solve(int ine,int mx){
for(int i=1;i<=m;i++){
if(c[i]==ine&&num[ine]<mx){
int fx=find(u[i]);int fy=find(v[i]);
if(fx!=fy){
vis[i]=1;f[fx]=fy;num[ine]++;
au[++top]=u[i];av[top]=v[i];ac[top]=c[i];
}
}
}
}
int main(){
//freopen("All.in","r",stdin);
//freopen("zh.out","w",stdout);
n=read();m=read();int k=read();
for(int i=1;i<=m;i++){
u[i]=read();v[i]=read();c[i]=read();
}
for(int i=1;i<=n;i++) f[i]=i;
solve(1,inf);solve(0,inf);
if(num[1]+num[0]!=n-1||num[0]>k){
cout<<"no solution"<<endl;
return 0;
}
top=0;num[0]=num[1]=0;
for(int i=1;i<=n;i++) f[i]=i;
for(int i=1;i<=m;i++){
if(vis[i]&&c[i]==0){
int fx=find(u[i]);
int fy=find(v[i]);
if(fx!=fy){
au[++top]=u[i];av[top]=v[i];ac[top]=c[i];
num[0]++;f[fx]=fy;
}
}
}
solve(0,k);solve(1,inf);
if(num[0]<k){
cout<<"no solution"<<endl;
return 0;
}
for(int i=1;i<=top;i++){
printf("%d %d %d\n",au[i],av[i],ac[i]);
}
return 0;
}