NOIPの模拟_2016_7_20_t2_Graph Coloring
2016-07-20 19:47
274 查看
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
现在你有一张无向图包含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”每一次可以把与一个点相邻的边全部换一种颜色(红变蓝蓝变红~)求最少的步数比赛时の想法:
首先观摩一下数据の规模,105级别,于是就开始想nlogn的做法想着想着发现每一个点最多只会按一次,这是十分显然的,因为按两次对答案的贡献就为零了,于是在这个基础上继续想,然后我就发现如果边的目标颜色以及当前颜色确定,而且有一边的颜色确定,那么另外一边的颜色也是确定的。当时就想着可以分颜色选什么和第一个点取不取4种情况讨论,但是这个想法很好显然是错误的 233333333333解法:
在前面想法的基础上,我们可以发现那个图不一定是一个联通图,ta可能是由多个块组成的,那么我们可以先做一次bfs分块,然后分全部染成红色和全部染成蓝色两种情况讨论,由与每个块都是相对独立的,于是我们可以对每个块分开讨论,对于每个块我们也是分成第一个点取或不取讨论,然后把对于每一个块取或不取的较小的答案加起来,然后把染成红色和染成蓝色需要的步数比较一下,输出较小的那个就可以了。注意如果在做某一个块时出现了不合法的情况,那么后面的块都不用做了,对于这个目标颜色所需“步数”为-1。吐槽
哈哈哈哈又到了吐槽的时间啦,因为我太垃圾了,所以打的代码也很捞,别人2000byte的代码量被我强行打到6500byte,结果超级难调,看来要早日皈依C++了红红火火恍恍惚惚。代码
稍微看一下就可以理解的超好超级垃圾的代码233var 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.
相关文章推荐
- [283] Move Zeroes
- centos6.3 安装配置redis
- Codeforces Round #363 D Fix a Tree(并查集)
- UVA 657 The die is cast
- (面试)指针与数组的区别
- Simplify Path
- codeforces C. Hometask(贪心)
- [置顶] Android6.0权限适配的那些坑
- hdu 5726 GCD 倍增+ 二分
- iOS-RAC学习笔记(一)——RACStream
- TotoiseSVN-小乌龟的使用方法
- 交叉编译Qt5.5.1 with egl (2)
- HDOJ 1002 A + B Problem II
- 用IntelliJ IDEA创建Gradle项目简单入门
- 指针和数组的区别
- 【杭电-oj】-4548-美素数(打表)
- poj 1062 昂贵的聘礼(DFS)
- Mac搭建Hexo博客及NexT主题配置优化
- 简单的面包屑数据
- java 二、八、十、十六进制之间的转换