HDU3062 Party
题目链接:HDOJ3062
题目大意:
有n对夫妻被邀请参加一个聚会,因为场地的问题,每对夫妻中只有1人可以列席。在2n 个人中,某些人之间有着很大的矛盾(当然夫妻之间是没有矛盾的),有矛盾的2个人是不会同时出现在聚会上的。有没有可能会有n 个人同时列席?
解题思路:
tarjan缩点判断即可
参考代码
1 #include <iostream> 2 #include <cstring> 3 #define N 2000001 4 using namespace std; 5 bool vis[2003]; 6 int tp,id,indx,cnt,n,m,a1,a2,c1,c2,head[2001],nxt[N],to[N],dfn[2001],low[2001],s[2001],col[2001]; 7 inline int read() 8 { 9 int x = 0, y = 1; char c = getchar(); while(c < '0' || c > '9') {if(c == '-') y = -1; c = getchar();} while(c >= '0' && c <= '9') x = x*10+c-'0', c = getchar(); return x*y; 10 } 11 void add(int u, int v) 12 { 13 nxt[++cnt] = head[u]; 14 head[u] = cnt; 15 to[cnt] = v; 16 } 17 void tarjan(int u) // 缩点 18 { 19 dfn[u] = low[u] = ++id; s[++tp] = u; vis[u] = true; 20 for(int i = head[u]; ~i; i = nxt[i]) 21 { 22 int v = to[i]; 23 if(!dfn[v]) 24 { 25 tarjan(v); 26 low[u] = min(low[u],low[v]); 27 } else if(vis[v]) low[u] = min(low[u],low[v]); 28 } 29 if(dfn[u] == low[u]) 30 { 31 vis[u] = false; 32 col[u] = ++indx; 33 while(s[tp] != u) 34 { 35 vis[s[tp]] = false; 36 col[s[tp]] = indx; 37 tp--; 38 } 39 tp--; 40 } 41 } 42 bool solve() // 如果有一对夫妻出现在同一个scc中,则不满足条件 43 { 44 for(int i = 0; i < 2*n; i+=2) // 注意+=2 45 if(col[i] == col[i+1]) 46 return true; 47 return false; 48 } 49 void init() 50 { 51 cnt = -1; 52 tp = id = indx = 0; 53 memset(head,-1,sizeof(head)); 54 memset(vis,false,sizeof(vis)); 55 memset(dfn,0,sizeof(dfn)); 56 memset(low,0,sizeof(low)); 57 memset(col,0,sizeof(col)); 58 memset(nxt,0,sizeof(nxt)); 59 memset(to,0,sizeof(to)); 60 memset(s,0,sizeof(s)); 61 } 62 int main() 63 { 64 while(~scanf("%d%d",&n,&m)) 65 { 66 init(); 67 for(int i = 0; i < m; i++) 68 { 69 a1 = read(); a2 = read(); c1 = read(); c2 = read(); 70 add(2*a1+c1, 2*a2+1-c2); // 加边,2*a是妻子,2*a+1是丈夫 71 add(2*a2+c2, 2*a1+1-c1); 72 } 73 for(int i = 0; i < 2*n; i++) 74 if(!dfn[i]) 75 tarjan(i); 76 if(solve()) puts("NO"); 77 else puts("YES"); 78 } 79 return 0; 80 }

浙公网安备 33010602011771号