[USACO2013 Jan]Liars and Truth Tellers真假奶牛
题目链接:..并没有找到
题目大意:
题解:
并查集
看清题意!说的是找最多的前K句话,而不是找最多的K句话qwq(不然我就不会做了..orz
句型有两种:
1、x说y是真的,那么x和y同真同假。
2、x说y是假的,那么x和y一真一假。
所以就有两种关系,可近似看成——“同盟”&"敌对"。
于是就是经典的并查集啦。
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define maxn 1100 int fa[maxn],em[maxn];//fa-同盟的 em-敌对 int ffind(int x) { if (fa[x]!=x) fa[x]=ffind(fa[x]); return fa[x]; } int main() { //freopen("truth.in","r",stdin); //freopen("truth.out","w",stdout); int n,m,x,y,i,bk=-1;char c; scanf("%d%d",&n,&m); for (i=1;i<=n;i++) {fa[i]=i;em[i]=-1;} // memset(pd,-1,sizeof(pd)); for (i=1;i<=m;i++) { scanf("%d%d %c",&x,&y,&c); if (bk!=-1) continue; if (c=='T') { int fx=ffind(fa[x]),fy=ffind(fa[y]); if (em[fx]==-1 || em[fy]==-1)//朋友的敌人是敌人 { fa[fy]=fx; if (em[fx]!=-1) em[fy]=em[fx]; else if (em[fy]!=-1) em[fx]=em[fy]; }else { int ex=ffind(em[fx]),ey=ffind(em[fy]); if (fx==ey || fy==ex) {bk=i;continue;}//有矛盾啦 fa[fy]=fx;fa[ex]=ey; } }else if (c=='L') { int fx=ffind(fa[x]),fy=ffind(fa[y]); if (fx==fy) {bk=i;continue;}//有矛盾啦 if (em[fx]==-1 || em[fy]==-1) { if (em[fx]!=-1) {em[fy]=fx;fa[fy]=em[fx];}//敌人的敌人是朋友 else if (em[fy]!=-1) {em[fx]=fy;fa[fx]=em[fy];} else em[fx]=fy,em[fy]=fx; }else { int ex=ffind(em[fx]),ey=ffind(em[fy]); fa[fx]=ey;fa[fy]=ex; } } } if (bk==-1) bk=m;else bk--; printf("%d\n",bk); return 0; }