NOIPの模拟_2016_7_20_t2_Graph Coloring
来源:互联网 发布:松下网络摄像机出厂ip 编辑:程序博客网 时间:2024/06/09 23:17
Description
现在你有一张无向图包含n个节点m条边。最初,每一条边都是蓝色或者红色。每一次你可以将一个节点连接的所有边变色(从红变蓝,蓝变红)。
找到一种步数最小的方案,使得所有边的颜色相同。
Input
第一行包含两个数n,m(1<=n,m<=100000)分别代表节点数和边的数量
接下来m行描述边,第i行ui,vi,ci,代表ui有一条颜色为ci的边与vi相连(ci是B或者是R),B代表蓝色,R代表红色。数据保证没有自环的边。
Output
如果没有方案就输出-1。否则第一行输出k代表最小的步数
Sample Input
输入1:
3 3
1 2 B
3 1 R
3 2 B
输入2:
3 3
1 2 B
3 1 R
3 2 B
输入3:
4 5
1 2 R
1 3 R
2 3 B
3 4 B
1 4 B
Sample Output
输出1:
1
输出2:
2
输出3:
-1
Data Constraint
对于30%数据,n<=20,m<=20
题目の大意:
给你一堆点,还有一堆边,每条边上有一个“R”或者“B”每一次可以把与一个点相邻的边全部换一种颜色(红变蓝蓝变红~)求最少的步数
比赛时の想法:
首先观摩一下数据の规模,显然是错误的 233333333333
解法:
在前面想法的基础上,我们可以发现那个图不一定是一个联通图,ta可能是由多个块组成的,那么我们可以先做一次bfs分块,然后分全部染成红色和全部染成蓝色两种情况讨论,由与每个块都是相对独立的,于是我们可以对每个块分开讨论,对于每个块我们也是分成第一个点取或不取讨论,然后把对于每一个块取或不取的较小的答案加起来,然后把染成红色和染成蓝色需要的步数比较一下,输出较小的那个就可以了。注意如果在做某一个块时出现了不合法的情况,那么后面的块都不用做了,对于这个目标颜色所需“步数”为-1。
吐槽
哈哈哈哈又到了吐槽的时间啦,因为我太垃圾了,所以打的代码也很捞,别人2000byte的代码量被我强行打到6500byte,结果超级难调,看来要早日皈依C++了红红火火恍恍惚惚。
代码
稍微看一下就可以理解的超好超级垃圾的代码233
var a,b:array[0..200005,1..2]of longint; color:array[0..200005]of char; bb,bz:array[0..100005]of boolean; cc,skt,h:array[0..100005]of longint; i,j,k,l,m,n,ans,tot,kk,ans1,ans2:longint;procedure qsort(l,r:longint);var i,j,mid:longint;begin i:=l; j:=r; mid:=a[(i+j) div 2,1]; repeat while a[i,1]<mid do inc(i); while a[j,1]>mid do dec(j); if i<=j then begin a[0]:=a[i]; a[i]:=a[j]; a[j]:=a[0]; color[0]:=color[i]; color[i]:=color[j]; color[j]:=color[0]; inc(i); dec(j); end; until i>j; if i<r then qsort(i,r); if l<j then qsort(l,j);end;procedure getred(zz:longint;ppp:boolean);var i,j,k,x,y:longint; xx:boolean;begin skt[0]:=0; tot:=0; if ppp=true then begin tot:=1; inc(skt[0]); skt[skt[0]]:=zz; end; i:=1; h[1]:=zz; bz[zz]:=true; j:=0; xx:=false; while j<i do begin if xx=true then break; inc(j); x:=h[j]; for k:=b[x,1] to b[x,2] do if k>0 then begin y:=a[k,2]; if bz[y]=true then begin if (color[k]='R') and (bb[x]<>bb[y]) then begin xx:=true; tot:=-1; break; end else if (color[k]='B') and (bb[x]=bb[y]) then begin xx:=true; tot:=-1; break; end; end else begin bz[y]:=true; if color[k]='R' then begin if bb[x]=false then bb[y]:=false else begin bb[y]:=true; inc(tot); inc(skt[0]); skt[skt[0]]:=y; end; end else begin if bb[x]=false then begin bb[y]:=true; inc(tot); inc(skt[0]); skt[skt[0]]:=y; end else bb[y]:=false; end; inc(i); h[i]:=y; end; end; end; if (tot<ans) and (tot<>-1) then ans:=tot; for j:=1 to i do bz[h[j]]:=false; for j:=1 to skt[0] do bb[skt[j]]:=false;end;procedure init;begin readln(n,m); for i:=1 to m do begin readln(a[i,1],a[i,2],color[i],color[i]); a[m+i,1]:=a[i,2]; a[m+i,2]:=a[i,1]; color[m+i]:=color[i]; end; m:=m*2; qsort(1,m); b[a[1,1],1]:=1; for i:=2 to m do if a[i,1]<>a[i-1,1] then begin b[a[i-1,1],2]:=i-1; b[a[i,1],1]:=i; end; b[a[m,1],2]:=m;end;procedure getblue(zz:longint;ppp:boolean);var i,j,k,x,y:longint; xx:boolean;begin skt[0]:=0; tot:=0; if ppp=true then begin tot:=1; inc(skt[0]); skt[skt[0]]:=zz; end; i:=1; h[1]:=zz; bz[zz]:=true; j:=0; xx:=false; while j<i do begin if xx=true then break; inc(j); x:=h[j]; for k:=b[x,1] to b[x,2] do if k>0 then begin y:=a[k,2]; if bz[y]=true then begin if (color[k]='B') and (bb[x]<>bb[y]) then begin xx:=true; tot:=-1; break; end else if (color[k]='R') and (bb[x]=bb[y]) then begin xx:=true; tot:=-1; break; end; end else begin bz[y]:=true; if color[k]='B' then begin if bb[x]=false then bb[y]:=false else begin bb[y]:=true; inc(tot); inc(skt[0]); skt[skt[0]]:=y; end; end else begin if bb[x]=false then begin bb[y]:=true; inc(tot); inc(skt[0]); skt[skt[0]]:=y; end else bb[y]:=false; end; inc(i); h[i]:=y; end; end; end; if (tot<ans) and (tot<>-1) then ans:=tot; for j:=1 to i do bz[h[j]]:=false; for j:=1 to skt[0] do bb[skt[j]]:=false;end;procedure bfs(x:longint);var i,j:longint; q:array[0..100005]of longint;begin i:=1; j:=0; fillchar(q,sizeof(q),0); q[1]:=x; inc(k); // cc[x]:=k; while j<i do begin inc(j); for l:=b[q[j],1] to b[q[j],2] do if bb[a[l,2]]=false then begin // cc[a[l,2]]:=k; inc(i); q[i]:=a[l,2]; bb[a[l,2]]:=true; end; end;end;procedure de;begin k:=0; for i:=1 to n do if bb[i]=false then begin bfs(i); cc[k]:=i; end; fillchar(bb,sizeof(bb),false);end;begin // assign(input,'2.in'); reset(input); init; de; kk:=k; for i:=1 to kk do begin // fillchar(bb,sizeof(bb),false); bb[cc[i]]:=true; ans:=maxlongint; getred(cc[i],true); // fillchar(bb,sizeof(bb),false); getred(cc[i],false); if ans=maxlongint then ans:=-1; if ans=-1 then begin ans1:=-1; break; end; ans1:=ans1+ans; end; for i:=1 to kk do begin // fillchar(bb,sizeof(bb),false); bb[cc[i]]:=true; ans:=maxlongint; getblue(cc[i],true); // fillchar(bb,sizeof(bb),false); getblue(cc[i],false); if ans=maxlongint then ans:=-1; if ans=-1 then begin ans2:=-1; break; end; ans2:=ans2+ans; end; if ans1=-1 then begin if ans2=-1 then writeln(-1) else writeln(ans2); end else begin if ans2=-1 then writeln(ans1) else begin if ans2>ans1 then writeln(ans1) else writeln(ans2); end; end; // close(input);end.
- NOIPの模拟_2016_7_20_t2_Graph Coloring
- NOIPの模拟_2016_7_19_t1_腐败
- NOIPの模拟_2016_8_11_t2_种树
- NOIPの模拟_2016_8_14_t1_传送带
- Noip模拟
- 【NOIP模拟】20151004模拟
- 【NOIP模拟】 20151005模拟
- 【NOIP模拟】 20151006模拟
- 【NOIP模拟】 20151007模拟
- 【NOIP模拟】20151014模拟
- 【NOIP模拟】20151015模拟
- NOIPの模拟_2016_7_19_t2_弄提纲
- NOIPの模拟2016_8_11_t1_钱仓
- NOIPの模拟_2016_8_14_t2_疯狂的火神
- 【09 NOIP 模拟】light
- [NOIP模拟]Day1
- 8.9CH NOIP模拟
- 8.10FCH NOIP模拟
- cordova调用摄像机,并上传文件
- (面试)指针与数组的区别
- [网络流]poj3281 Dining
- UVA657The die is cast
- [283] Move Zeroes
- NOIPの模拟_2016_7_20_t2_Graph Coloring
- 函数三要数,函数调用
- 【NOIP2007提高组T3】矩阵取数游戏-动态规划+高精度
- HDU 4597 Play Game[博弈论 负值最大函数 记忆化搜索]
- 使用UUID可以产生一个号称全球唯一的ID
- Checkable API详解
- 一个非计算机专业的安卓工程师成长之路
- Java基础之数组
- 分数加减法