http://www.spoj.com/problems/PARADOX/
这题不知道为啥被归成dfs,一艘题解,甚是惊讶,竟然找出规律来了,佩服+1
多种讨论http://www.quora.com/What-is-the-algorithmic-approach-to-solving-the-problem-Paradox-on-SPOJ
A straightforward problem, if you can observed that there will be PARADOX if and only if there will be cycle containing an statement and having odd number of false implies in that cycle.
For example,
A -> B
B-> C
C -> A
There will be a contradiction at vertex A as in the Cycle A->B->C->A there will be number of false.
A simple ASAP algorithm will check that. Simply assign edge weight 1 if statement a is saying statement b is false, and 2 as true and check whether path length from A to A having odd length.
#include <iostream>
using namespace std;
#define MX 10000000
int main() {
// your code goes here
int T;
while(1)
{
int N,i,j,k;
cin>>N;
if(N==0)
return 0;
int dis[N+1][N+1];
for(i=0; i<=N ; i++)
for(j=0 ; j<=N ; j++)
dis[i][j] = MX;
for(i=1 ; i<=N ; i++)
{
int x;
string str;
cin>>x>>str;
if(str == "true")
dis[i][x] = 2;
else
dis[i][x] = 1;
}
for(k=1;k<=N;k++)
{
for(i=1;i<=N;i++)
{
for(j=1;j<=N;j++)
{
if(dis[i][j]>dis[i][k]+dis[k][j])
{
dis[i][j]=dis[i][k]+dis[k][j];
}
}
}
}
int temp=0;
for(i=1 ; i<=N ; i++)
{
if( dis[i][i] < MX/ 2 && dis[i][i] % 2 == 1)
{
cout<<"PARADOX"<<endl;
temp = 1;
break;
}
}
if(temp == 0)
{
cout<<"NOT PARADOX"<<endl;
}
}
return 0;
}