2018 百度之星 初赛 第六题

Posted stranger-

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 1001T100,1 leq n,m leq 1001n,m100,1 leq a,b leq n1a,bn,1 leq w leq 10001w1000,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("
");
  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:
",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 }
View Code

 





以上是关于2018 百度之星 初赛 第六题的主要内容,如果未能解决你的问题,请参考以下文章

2018 “百度之星”程序设计大赛 - 初赛(B)

2018 “百度之星”程序设计大赛 - 初赛(A)

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

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

2018 “百度之星”程序设计大赛 - 初赛(A)

2018 “百度之星”程序设计大赛 - 初赛(A)度度熊学队列 list rope