Let‘s go home
Time Limit: 10000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1435 Accepted Submission(s): 573
Problem Description
小时候,乡愁是一枚小小的邮票,我在这头,母亲在那头。
—— 余光中
集训是辛苦的,道路是坎坷的,休息还是必须的。经过一段时间的训练,lcy决定让大家回家放松一下,但是训练还是得照常进行,lcy想出了如下回家规定,每一个队(三人一队)或者队长留下或者其余两名队员同时留下;每一对队员,如果队员A留下,则队员B必须回家休息下,或者B留下,A回家。由于今年集训队人数突破往年同期最高记录,管理难度相当大,lcy也不知道自己的决定是否可行,所以这个难题就交给你了,呵呵,好处嘛~,免费**漂流一日。
Input
第一行有两个整数,T和M,1<=T<=1000表示队伍数,1<=M<=5000表示对数。
接下来有T行,每行三个整数,表示一个队的队员编号,第一个队员就是该队队长。
然后有M行,每行两个整数,表示一对队员的编号。
每个队员只属于一个队。队员编号从0开始。
Output
可行输出yes,否则输出no,以EOF为结束。
Sample Input
1 2
0 1 2
0 1
1 2
2 4
0 1 2
3 4 5
0 3
0 4
1 3
1 4
Sample Output
yes
no
Author
威士忌
题意在题目阐述得很明确 。
那么 , 很确定的是 ,要么 队长留下 , 要么2名队员留下。
然后对于 t对 队员 , 不能同时留下, 也不能同时不留下。
可以看出 , 同一队的两名非队长队员可以看成一个点 , 队长可以看成一个点 。
然后用 map 把他们的编号映射成一个新的编号 , 然后用新的编号去构图 。
构出无向边 u - v
表示 u 与 v 只能有一个成立 。
那么在dfs 的时候 u 成立 , v^1 就必须成立 。
#include <iostream> #include <cstdio> #include <cstring> #include <stack> #include <map> using namespace std; const int N = 2010; const int M = 10010; int n , m ; int st[N] , top ; bool mark[N]; int eh[N] , et[M] , nxt[M] , tot ; map<int,int>mp; void init() { mp.clear(); tot = 0 ; memset( eh , -1 , sizeof eh ); memset( mark , false , sizeof mark ); } void addedge( int u , int v ){ et[tot] = v , nxt[tot] = eh[u] , eh[u] = tot ++ ; et[tot] = u , nxt[tot] = eh[v] , eh[v] = tot ++ ; } bool dfs( int u ) { if( mark[u] ) return true; if( mark[u^1] ) return false; mark[u] = true ; st[top++] = u ; for( int i = eh[u] ; ~i ; i = nxt[i] ){ int v = et[i]; if( !dfs(v^1) ) return false; } return true; } bool solve() { for(int i = 0 ; i < 2 * n ; i += 2 ){ if( !mark[i] && !mark[i+1] ){ top = 0 ; if( !dfs(i) ){ while( top > 0 ) mark[ st[--top] ] = false; if( !dfs(i+1) ) return false ; } } } return true; } int main() { #ifdef LOCAL freopen("in.txt","r",stdin); #endif // LOCAL ios::sync_with_stdio(0); int x1 , x2 , x3 ; while( cin >> n >> m ){ init(); for( int i = 0 ; i < n ; ++i ){ cin >> x1 >> x2 >> x3 ; mp[x1] = 2 * i ; mp[x2] = 2 * i + 1 ; mp[x3] = 2 * i + 1 ; } for( int i = 0 ; i < m ; ++i ){ cin >> x1 >> x2 ; x1 = mp[x1] ; x2 = mp[x2] ; addedge( x1 , x2 ); } if( solve() ) cout << "yes" << endl; else cout << "no" << endl; } }
HDU 1824 Let's go home