ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2018百度之星入围赛T6三原色图

2021-01-31 08:33:49  阅读:220  来源: 互联网

标签:opt ch Jay T6 int le 2018 条边 三原色


题目背景

2018百度之星入围赛T6

题目描述

\(Jay\) 有一张 \(n\) 个点 \(m\) 条边的无向图, 所有点按照 \(1,2,⋯,n\) 标号, 每条边有一
个正整数权值以及一种色光三原色红、 绿、 蓝之一的颜色。
现在 \(Jay\) 想选出恰好 \(k\) 条边,满足只用这 \(k\) 条边之中的红色边和绿色边就能使 \(n\)
个点之间两两连通, 或者只用这 \(k\) 条边之中的蓝色边和绿色边就能使 \(n\) 个点之
间两两连通, 这里两个点连通是指从一个点出发沿着边可以走到另一个点。
对于每个 \(k \in [1,m],k \in Z\) , 你都需要帮 \(Jay\) 计算选出恰好 \(k\) 条满足条件的边的权值之和的最小值。

\(1 \le n, m \le 100\)

$1 \le $ 边权 \(w \le 1000\)

题解

一道最小生成树练手好题 ,不需要什么复杂的技巧,理解了原理就可以。

以蓝绿,红绿为所选颜色跑两遍最小生成树。一旦能够生成树,剩下的边就从小到大排序,依次选完。

注意事项

一定要判断能不能生成最小生成树!!!

排序只需要排一次。

分清楚哪里\(break\) ,哪里\(continue\) 。

\(n==1\)时好像要输出一个\(0\)

Code

#include<bits/stdc++.h>
#define N (220)
using namespace std;
struct xbk{int st,ed,v;char f;}e[N];
char opt;
int T,n,m,sum,cnt,flag,now[N],fa[N],ans1[N],ans2[N];
bool flag1,flag2,used[N];
inline int read(){
	int w=0;
	char ch=getchar();
	while(ch>'9'||ch<'0') ch=getchar();
	while(ch>='0'&&ch<='9'){
		w=(w<<3)+(w<<1)+(ch^48);
		ch=getchar();
	}
	return w;
}
inline bool cmp(xbk a,xbk b){return a.v<b.v;}
inline int mfind(int x){
	if(fa[x]!=x) return fa[x]=mfind(fa[x]);
	return fa[x];
}
inline void init(){
	cnt=0;
	memset(now,0,sizeof(now));
	memset(used,0,sizeof(used));
	for(int i=1;i<=m;i++) fa[i]=i;
}
inline void Solo(){
	init();
	for(int i=1;i<=m;i++){
		int nx=mfind(e[i].st),ny=mfind(e[i].ed);
		if(nx==ny||e[i].f=='R') continue;
		fa[nx]=ny;
		used[i]=1;
		cnt++;
		ans1[cnt]=ans1[cnt-1]+e[i].v;
		if(cnt==n-1){
			flag1=1;
			int tot=0;
			for(int j=1;j<=m;j++) if(!used[j]) now[++tot]=e[j].v;
			sort(now+1,now+1+tot);
			for(int j=1;j<=tot;j++) ans1[j+cnt]=ans1[j+cnt-1]+now[j];
			break;
		}
	}
	init();
	for(int i=1;i<=m;i++){
		int nx=mfind(e[i].st),ny=mfind(e[i].ed);
		if(nx==ny||e[i].f=='B') continue;
		fa[nx]=ny;
		used[i]=1;
		cnt++;
		ans2[cnt]=ans2[cnt-1]+e[i].v;
		if(cnt==n-1){
			flag2=1;
			int tot=0;
			for(int j=1;j<=m;j++) if(!used[j]) now[++tot]=e[j].v;
			sort(now+1,now+1+tot);
			for(int j=1;j<=tot;j++) ans2[j+cnt]=ans2[j+cnt-1]+now[j];
			break;
		}
	}
	return;
}
int main(){
	T=read();
	while(T--){
		printf("Case #%d",++flag);
		puts(":");
		n=read(),m=read();
		for(int i=1;i<=m;i++){
			e[i].st=read(),e[i].ed=read(),e[i].v=read();
			cin>>opt;
			e[i].f=opt;
		}
		sort(e+1,e+1+m,cmp);
		if(n==1){
			int nw=0;
			puts("0");
			for(int i=1;i<=m;i++){
				nw+=e[i].v;
				printf("%d\n",nw);
			}
			continue;
		}
		flag1=0,flag2=0;
		Solo();
		if(!flag1&&!flag2){
			for(int i=1;i<=m;i++) puts("-1");
			continue;
		}
		for(int i=1;i<=m;i++){
			if(i<n-1){puts("-1");continue;}
			if(flag1&&!flag2) printf("%d\n",ans1[i]);
			if(flag2&&!flag1) printf("%d\n",ans2[i]);
			if(flag1&&flag2) printf("%d\n",min(ans1[i],ans2[i]));
		}
	}
	return 0;
}

完结撒花❀

标签:opt,ch,Jay,T6,int,le,2018,条边,三原色
来源: https://www.cnblogs.com/xxbbkk/p/14351547.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有