2018 百度之星 初赛 第六题

三原色图

Accepts: 281

Submissions: 1261

Time Limit: 1500/1000 MS (Java/Others)

Memory Limit: 262144/262144 K (Java/Others)

Problem Description

度度熊有一张 nn 个点 mm 条边的无向图,所有点按照 1,2,\cdots,n1,2,?,n 标号,每条边有一个正整数权值以及一种色光三原色红、绿、蓝之一的颜色。

现在度度熊想选出恰好 kk 条边,满足只用这 kk 条边之中的红色边和绿色边就能使 nn 个点之间两两连通,或者只用这 kk 条边之中的蓝色边和绿色边就能使 nn 个点之间两两连通,这里两个点连通是指从一个点出发沿着边可以走到另一个点。

对于每个 k=1,2,\cdots,mk=1,2,?,m,你都需要帮度度熊计算选出恰好 kk 条满足条件的边的权值之和的最小值。

Input

第一行包含一个正整数 TT,表示有 TT 组测试数据。

接下来依次描述 TT 组测试数据。对于每组测试数据:

第一行包含两个整数 nn 和 mm,表示图的点数和边数。

接下来 mm 行,每行包含三个整数 a,b,wa,b,w 和一个字符 cc,表示有一条连接点 aa 与点 bb 的权值为 ww、颜色为 cc 的无向边。

保证 1 \leq T \leq 1001≤T≤100,1 \leq n,m \leq 1001≤n,m≤100,1 \leq a,b \leq n1≤a,b≤n,1 \leq w \leq 10001≤w≤1000,c \in {R,G,B}c∈{R,G,B},这里 R,G,BR,G,B 分别表示红色、绿色和蓝色。

Output

对于每组测试数据,先输出一行信息 "Case #x:"(不含引号),其中 x 表示这是第 xx 组测试数据,接下来 mm 行,每行包含一个整数,第 ii 行的整数表示选出恰好 ii 条满足条件的边的权值之和的最小值,如果不存在合法方案,输出 -1?1,行末不要有多余空格。

Sample Input

1
5 8
1 5 1 R
2 1 2 R
5 4 5 R
4 5 3 G
1 3 3 G
4 3 5 G
5 4 1 B
1 2 2 B

Sample Output

Case #1:
-1
-1
-1
9
10
12
17
22

解析 直接建图 判断连不连通 跑最小生成树  特判1个点的情况。

AC代码

  1 #include <bits/stdc++.h>
  2 #define pb push_back
  3 #define mp make_pair
  4 #define fi first
  5 #define se second
  6 #define all(a) (a).begin(), (a).end()
  7 #define fillchar(a, x) memset(a, x, sizeof(a))
  8 #define huan printf("\n");
  9 #define debug(a,b) cout<<a<<" "<<b<<" "<<endl;
 10 using namespace std;
 11 typedef long long ll;
 12 const int maxn=150+10,inf=0x3f3f3f3f;
 13 const ll mod=1e9+7;
 14 int n,m;
 15 int p[maxn],par[maxn],g[maxn][maxn];
 16 struct edge
 17 {
 18     int u,v,w,id;
 19     char col;
 20 } a[maxn],b[maxn],c[maxn];
 21 int cmp(edge a,edge b)
 22 {
 23     return a.w<b.w;
 24 }
 25 int find_(int x)
 26 {
 27     return p[x]==x?x:p[x]=find_(p[x]);
 28 }
 29 int _find(int x)
 30 {
 31     return x==par[x]?x:par[x]=_find(par[x]);
 32 }
 33 void unio(int a,int b)
 34 {
 35     int ra=_find(a);
 36     int rb=_find(b);
 37     if(ra!=rb)
 38         par[rb]=ra;
 39 }
 40 int ans1[maxn],ans2[maxn];
 41 int main()
 42 {
 43     int t,kase=1;
 44     cin>>t;
 45     while(t--)
 46     {
 47         map<int,int> mp;
 48         scanf("%d %d",&n,&m);
 49         int u,v,w;
 50         for(int i=0; i<m; i++)
 51         {
 52             cin>>a[i].u>>a[i].v>>a[i].w>>a[i].col;
 53             a[i].id=i;
 54         }
 55         printf("Case #%d:\n",kase++);
 56         sort(a,a+m,cmp);
 57         //for(int i=0;i<m;i++)
 58            // debug(a[i].w,a[i].col);
 59         if(n==1)
 60         {
 61             int sum=0;
 62             for(int i=0; i<m; i++)
 63             {
 64                 sum+=a[i].w;
 65                 cout<<sum<<endl;
 66             }
 67             continue;
 68         }
 69 //------------------------------------------------------------------------------
 70         int cnt=0,flag1=1;mp.clear();
 71         memset(g,inf,sizeof(g));
 72         memset(ans1,inf,sizeof(ans1));
 73         for(int i=1; i<=n; i++)
 74             p[i]=i,par[i]=i;
 75         for(int i=0; i<m; i++)
 76         {
 77             if((a[i].col==‘R‘||a[i].col==‘G‘)&&a[i].w<g[a[i].u][a[i].v]&&a[i].u!=a[i].v)
 78             {
 79                 g[a[i].u][a[i].v]=g[a[i].v][a[i].u]=a[i].w;
 80                 b[cnt++]= {a[i].u,a[i].v,a[i].w,a[i].id,a[i].col};
 81                 unio(a[i].u,a[i].v);
 82             }
 83         }
 84         for(int i=2; i<=n; i++)
 85             if(_find(i-1)!=_find(i))flag1=0;
 86         if(flag1)
 87         {
 88             sort(b,b+cnt,cmp);
 89             ans1[n-1]=0;
 90             for(int i=0; i<cnt; i++)
 91             {
 92                 int x,y,z;
 93                 x=find_(b[i].u),y=find_(b[i].v),z=b[i].w;
 94                 if(x!=y)
 95                 {
 96                     ans1[n-1]+=z;
 97                     mp[b[i].id]=1;
 98                     p[x]=y;
 99                 }
100             }
101             int k=n;
102             for(int i=0; i<m; i++)
103             {
104                 if(mp[a[i].id]==0)
105                     ans1[k]=ans1[k-1]+a[i].w,k++;
106             }
107         }
108 //---------------------------------------------------------------------------------------------
109         int flag2=1;cnt=0;mp.clear();
110         memset(g,inf,sizeof(g));
111         memset(ans2,inf,sizeof(ans2));
112         for(int i=1; i<=n; i++)
113             p[i]=i,par[i]=i;
114         for(int i=0; i<m; i++)
115         {
116             if((a[i].col==‘B‘||a[i].col==‘G‘)&&a[i].w<g[a[i].u][a[i].v]&&a[i].u!=a[i].v)
117             {
118                 g[a[i].u][a[i].v]=g[a[i].v][a[i].u]=a[i].w;
119                 b[cnt++]={a[i].u,a[i].v,a[i].w,a[i].id,a[i].col};
120                 unio(a[i].u,a[i].v);
121             }
122         }
123         for(int i=2; i<=n; i++)
124             if(_find(i-1)!=_find(i))flag2=0;
125         if(flag2==0&&flag1==0)
126         {
127             for(int i=1;i<=m; i++)
128                 cout<<-1<<endl;
129             continue;
130         }
131         if(flag2)
132         {
133
134             sort(b,b+cnt,cmp);
135             ans2[n-1]=0;
136             for(int i=0; i<cnt; i++)
137             {
138                 int x,y,z;
139                 x=find_(b[i].u),y=find_(b[i].v),z=b[i].w;
140                 if(x!=y)
141                 {
142                     ans2[n-1]+=z;
143                     mp[b[i].id]=1;
144                     p[x]=y;
145                 }
146             }
147             int k=n;
148             for(int i=0; i<m; i++)
149             {
150                 if(mp[a[i].id]==0)
151                     ans2[k]=ans2[k-1]+a[i].w,k++;
152             }
153         }
154         for(int i=1; i<n-1; i++)
155             cout<<-1<<endl;
156         for(int i=n-1; i<=m; i++)
157         {
158             cout<<min(ans1[i],ans2[i])<<endl;
159         }
160     }
161 }

原文地址:https://www.cnblogs.com/stranger-/p/9420169.html

时间: 2024-10-06 00:12:12

2018 百度之星 初赛 第六题的相关文章

2018百度之星初赛B - A,D,F

总结:这一次的百度之星之行到这里也就结束了,充分的认识到了自己的不足啊...果然还是做的题太少,,见识的题型也还太少,对于STL的掌握还是不够到位啊!!(STL大法是真的好,建议大家认认真真的好好学学),这一次在一群大佬中被狂虐,下来之后还是继续刷题吧,希望明年继续加油!!!(共勉,加油!) A. degree Problem Description 度度熊最近似乎在研究图论.给定一个有 NN 个点 (vertex) 以及 MM 条边 (edge) 的无向简单图 (undirected simp

百度之星初赛一 补题

1001 小C的倍数问题 题意: 根据小学数学的知识,我们知道一个正整数x是3的倍数的条件是x每一位加起来的和是3的倍数.反之,如果一个数每一位加起来是3的倍数,则这个数肯定是3的倍数. 现在给定进制P,求有多少个B满足P进制下,一个正整数是B的倍数 的充分必要条件是每一位加起来的和是B的倍数. 我真是一句mmp啊   wcnmlgb 题目读了半天没读懂  后面的签到题也没心思写了 看了别人的题解  也算是明白了  自己真的是菜的可以啊 详细解答:http://blog.csdn.net/qq_

2018&quot;百度之星&quot;程序设计大赛 - 资格赛 - 题集

1001 $ 1 \leq m \leq 10 $ 像是状压的复杂度. 于是我们(用二进制)枚举留下的问题集合 然后把这个集合和问卷们的答案集合 $ & $ 一下 就可以只留下被选中的问题的答案了. 之后扫一遍随便判一下重. 1002 非空子串中字典序最小的子串长度一定是 $ 1 $ . 咱们就记录一下每一个字母出现次数的前缀和, 每次询问就找到出现过的最先的那个字符就星了. 1003 整数规划好像是个NPC问题, 所以我们肯定不能直接上整数规划. 咱们来尝试把问题转换一下. n=2 x1---

【2018百度之星初赛(A)】1002 度度熊学队列

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=6375 Knowledge Point: STL - map:https://www.cnblogs.com/liubilan/p/9458765.html STL - deque:https://www.cnblogs.com/liubilan/p/9461141.html 这道题主要考的是STL容器的使用,没有写出来只说明了一个道理: STL很重要啊!目前你用到的没用到的你都得了解并且会使用啊!!

2019 年百度之星—初赛一 B题 Game

题目链接 题意:最开始可以选择任意位置,在一个坐标轴上,依次走到一个区间里面,可以选择走一步两步,求最小步数. 思路:贪心,刚开始合并区间,确定初始位置以及方向.往右走肯定到左端点,往左走先到右端点,判断下个区间的和下下个区间的方向是否一致,一致如果到是奇数,则当偶数处理位置,反之,仍然走到 端点上.wa了很多次,细节没注意好. #include<iostream> #include<algorithm> #include<string> #include<cst

2014百度之星初赛(第二场)——Best Financing

2014百度之星初赛(第二场)--Best Financing Problem Description 小A想通过合理投资银行理财产品达到收益最大化.已知小A在未来一段时间中的收入情况,描述为两个长度为n的整数数组dates和earnings,表示在第dates[i]天小A收入earnings[i]元(0<=i<n).银行推出的理财产品均为周期和收益确定的,可描述为长度为m的三个整数数组start.finish和interest_rates, 若购买理财产品i(0<=i<m),需要

2014 百度之星初赛题解1001 - Energy Conversion

Problem Description 魔法师百小度也有遇到难题的时候-- 现在,百小度正在一个古老的石门面前,石门上有一段古老的魔法文字,读懂这种魔法文字需要耗费大量的能量和大量的脑力. 过了许久,百小度终于读懂魔法文字的含义:石门里面有一个石盘,魔法师需要通过魔法将这个石盘旋转X度,以使上面的刻纹与天相对应,才能打开石门. 但是,旋转石盘需要N点能量值,而为了解读密文,百小度的能量值只剩M点了!破坏石门是不可能的,因为那将需要更多的能量.不过,幸运的是,作为魔法师的百小度可以耗费V点能量,使

2016&quot;百度之星&quot; - 初赛(Astar Round2A)解题报告

此文章可以使用目录功能哟↑(点击上方[+]) 有点智商捉急,第一题卡了好久,看来不服老,不服笨是不行的了...以下是本人目前的题解,有什么疑问欢迎提出 链接→2016"百度之星" - 初赛(Astar Round2A)  Problem 1001 All X Accept: 0    Submit: 0 Time Limit: 2000/1000 mSec(Java/Others)    Memory Limit : 65536 KB  Problem Description F(x,

HDU 5701 中位数计数( 2016&quot;百度之星&quot; - 初赛(Astar Round2B) 思维 + 暴力)

传送门 中位数计数 Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 852 Accepted Submission(s): 335 Problem Description 中位数定义为所有值从小到大排序后排在正中间的那个数,如果值有偶数个,通常取最中间的两个数值的平均数作为中位数. 现在有n个数,每个数都是独一无二的,求出每个数在多少个包含