POJ1291 This Sentence is False 并查集

此题先按照要求并查集处理,与2SAT相似,i与i+n是对立的点,不能出现在一个集合中,如果所数据处理完后,无矛盾,那么则将i与i+n两个对立的集合中的最大值加到ans中即可

 

This Sentence is False
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 793 Accepted: 338

Description

The court of King Xeon 2.4 is plagued with intrigue and conspiracy. A document recently discovered by the King's Secret Service is thought to be part of some mischievous scheme. The document contains simply a set of sentences which state the truth or falsehood of each other. Sentences have the form "Sentence X is true/false" where X identifies one sentence in the set. The King's Secret Service suspects the sentences in fact refer to another, yet uncovered, document.
While they try to establish the origin and purpose of the document, the King ordered you to find whether the set of sentences it contains is consistent, that is, if there is a valid truth assignment for the sentences. If the set is consistent, the King wants you to determine the maximum number of sentences which can be made true in a valid truth assignment for the document.

Input

The input contains several instances of documents. Each document starts with a line containing a single integer,
N, which indicates the number of sentences in the document (1 <= N <= 1000). The following N lines contain each a sentence. Sentences are numbered sequentially, in the order they appear in the input (the first is sentence 1, the second is sentence 2, and so on). Each sentence has the form "Sentence X is true." or "Sentence X is false.", where 1 <= X <= N. The value N = 0 indicates the end of input.

Output

For each document in the input your program should output one line. If the document is consistent,your program should print the maximum number of sentences in a valid truth assignment for the document.Otherwise your program should print the word 'Inconsistent'.

Sample Input

1
Sentence 1 is false.
1
Sentence 1 is true.
5
Sentence 2 is false.
Sentence 1 is false.
Sentence 3 is true.
Sentence 3 is true.
Sentence 4 is false.
0

Sample Output

Inconsistent
1
3
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>

using namespace std;

#define MAXN 10000

int set[MAXN];
int n,ans;

void init(int n)
{
	for(int i=1;i<=n*2;i++)
		set[i]=i;
}

//查找a属于的集合编号
int find(int a)
{

	int root=a;
	int temp;
	while(set[root]!=root)
		root=set[root];
	while(set[a]!=root)
	{
		temp=a;
		a=set[a];
		set[temp]=root;
	}
	return root;
}

//合并两个集合
bool unions(int a,int b)
{
	int x=find(a);
	int y=find(b);
	if(x==y)
		return false;
	set[x]=y;
	return true;
}

char str[50];
int d;
bool jud(int i,int j)
{
    return find(i)==find(j);
}

int opt[MAXN],cnt[MAXN];
bool vis[MAXN];
void solve()
{
    memset(cnt,0,sizeof(cnt));
   for(int i=1;i<=n;i++)
   {
       cnt[find(i)]++;
       opt[find(i)]=find(i+n);
       opt[find(i+n)]=find(i);
   }
   int ans=0;
   memset(vis,0,sizeof(vis));
   for(int i=1;i<=n;i++)
   {
       if(vis[find(i)]||vis[find(i+n)]) continue;
       ans+=max(cnt[find(i)],cnt[find(i+n)]);
       vis[find(i)]=vis[find(i+n)]=1;
   }
   printf("%d\n",ans);
}

int main()
{
    while(~scanf("%d",&n)&& n)
    {
        bool flag=0;
        init(n);
        for(int i=1;i<=n;i++)
        {
            scanf("%s",str);
            scanf("%d",&d);
            scanf("%s",str);
            scanf("%s",str);
            if(flag) continue;
            if(strcmp(str,"false.")==0)
            {
                if(jud(i,d) || jud(i+n,d+n))
                    flag=1;
                else
                    unions(i,d+n),unions(i+n,d);
            }
            else
            {
                if(jud(i,d+n) || jud(i+n,d))
                    flag=1;
                else
                    unions(i,d),unions(i+n,d+n);
            }
        }
         if(flag)
                printf("Inconsistent\n");
        else
            solve();
    }
    return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值