两次Kruskal,记录最小的、输出,然后每多一条边(不同方案加的边不一定相同,有点坑),分别加在两个答案上,比较最小的输出。。
#include<cstdio>
#include<algorithm>
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;
const int N = 102;
const int M = 102;
int f[N];
struct Edge
{
int st,to,val;
char c[2];
bool flag1,flag2;
bool operator <(const Edge &t)const{
return val<t.val;
}
}edge[M];
void Init(int n)
{
for(int i = 1; i<=n; i++) f[i]=i;
}
int Find(int x)
{
if(x!=f[x]) f[x] = Find(f[x]);
return f[x];
}
bool Un(int x,int y)
{
x= Find(x); y = Find(y);
if(x!=y){
f[x] = y;
return 1;
}
return 0;
}
int Kruskal1(int n,int m)
{
int ans = 0,cnt = 0;
//sort(edge+1,edge+m+1);
for(int i = 1; i<=m; i++){
if(edge[i].c[0]!='B'&&Un(edge[i].st,edge[i].to)){
ans+=edge[i].val; edge[i].flag1=true;
cnt++;
} //printf("cnt %d\n",cnt);
}
if(cnt!=n-1) return inf;
return ans;
}
int Kruskal2(int n,int m)
{
int ans = 0,cnt = 0;
//sort(edge+1,edge+m+1);
for(int i = 1; i<=m; i++){
if(edge[i].c[0]!='R'&&Un(edge[i].st,edge[i].to)){
ans+=edge[i].val;
cnt++; edge[i].flag2=true;
} //printf("cnt %d\n",cnt);
}
if(cnt!=n-1) return inf;
return ans;
}
int main()
{
int t,n,m;
scanf("%d",&t);
for(int cas = 1; cas<=t; cas++)
{
memset(edge,0,sizeof(edge));
scanf("%d%d",&n,&m);
for(int i = 1; i<=m; i++){
scanf("%d%d%d%s",&edge[i].st,&edge[i].to,&edge[i].val,edge[i].c);
}
//for(int i = 1; i<=m; i++) printf("%d%d%d%s\n",edge[i].st,edge[i].to,edge[i].val,edge[i].c);
Init(n);
sort(edge+1,edge+m+1);
int ans1=Kruskal1(n,m);
// printf("%d\n",ans1);
Init(n);
int ans2=Kruskal2(n,m);
// printf("%d\n",ans2);
printf("Case #%d:\n",cas);
for(int i = 1; i<n-1; i++){
printf("-1\n");
}
if(ans1!=inf||ans2!=inf){
// if(ans1<ans2) {
printf("%d\n",min(ans1,ans2));
for(int i = n; i<=m; i++){
for(int k = 1; k<=m; k++){
if(!edge[k].flag1) {
ans1+=edge[k].val;
//printf("%d\n",ans1);
edge[k].flag1=true;
break;}
}
for(int k = 1; k<=m; k++){
if(!edge[k].flag2) {
ans2+=edge[k].val;
//printf("%d\n",ans2);
edge[k].flag2=true;
break;}
}
printf("%d\n",min(ans1,ans2));
}
// }
// else{
// printf("%d\n",ans2);
// for(int i = n; i<=m; i++){
// for(int k = 1; k<=m; k++){
// if(!edge[k].flag2) {
// ans2+=edge[k].val;
// printf("%d\n",ans2);
// edge[k].flag2=true;
// break;}
// }
// }
// }
}
else{
for(int i = n-1; i<=m; i++)
printf("-1\n");
}
}
return 0;
}