题目链接:..并没有找到
题目大意:
题解:
并查集
看清题意!说的是找最多的前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;
}