HDU 1824 Let's go home

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

时间: 2024-10-07 05:30:34

HDU 1824 Let's go home的相关文章

HDU 3062 &amp;&amp; HDU 1824 &amp;&amp; POJ 3578 &amp;&amp; BZOJ 1997 2-SAT

一条边<u,v>表示u选那么v一定被选. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 using namespace std; 6 const int Maxm=21000; 7 const int Maxn=2010; 8 struct EDGE{int to,next;}edge[Maxm]; 9 int T,m

HDU 1824 Let&#39;s go home (2-SAT)

题目地址:HDU 1824 这题可以把每队的两个队员看成一个,这样就是2-sat水题了... 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #include <ctype.h> #include <queue> #incl

HDU 1824

好吧,这次估计是明白边的含义了. X\/Y= -X->Y = -Y->X  这就达成了选了-X必须选Y的目的了.对于这道题,必须要明白题目了. 每一个队(三人一队)或者队长留下或者其余两名队员同时留下 : 就可以得到  X\/(Y^Z)=1 而不是互斥的. 以及  X->-Y     -X->Y 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include &l

HDU 1824 Let&amp;#39;s go home (2-SAT判定)

Let's go home Time Limit: 10000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1616    Accepted Submission(s): 661 Problem Description 小时候,乡愁是一枚小小的邮票,我在这头,母亲在那头. -- 余光中 集训是辛苦的.道路是坎坷的,歇息还是必须的.经过一段时间的训练,lcy决定让大家

HDU 1824 Let&#39;s go home (2-SAT判定)

Let's go home Time Limit: 10000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1616    Accepted Submission(s): 661 Problem Description 小时候,乡愁是一枚小小的邮票,我在这头,母亲在那头. -- 余光中 集训是辛苦的,道路是坎坷的,休息还是必须的.经过一段时间的训练,lcy决定让大家

(2 sat) hdu 1824

Let's go home Time Limit: 10000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1523    Accepted Submission(s): 616 Problem Description 小时候,乡愁是一枚小小的邮票,我在这头,母亲在那头.                        —— 余光中 集训是辛苦的,道路是坎坷的,休息还是

【图论】2-sat总结

2-sat总结 2-sat问题,一般表现的形式为.每一个点有两种方式a,b,要么选a,要么选b.而且点点之间有一些约束关系.比如:u和v至少一个选a.那么这就是一个表达式.把a当成真,b当成假,那就是u真或v真.2-sat的题目就是这样.给定这些约束,推断是否会矛盾 注意表达式的转化形式,(事实上就是离散数学中那几种转换方式) 比方(u真且v真)或(u假且v假)就能够转化成(u真或v假)且(u假或v真),这样就能建立关系 2-sat中的原理,事实上和2染色是一样的,把每一个结点拆分成一个真结点和

【小结】2-sat

2?sat 小结 2?sat解决的是可满足性问题,并且每个合取范式中的文字个数不多于2个. 形式为: (a∨?b)∧(?c∨?d)∧(?a∨d)? 将所有a∨b改成(?a?b)∧(?b?a) 建边,每个变量a对应两个点a和a+n 如果存在cmp[a]==cmp[a+n]不成立,否则成立.且如果cmp[a]>cmp[a+n],令a=true,否则令a=false即为原式的一组解. #include <cstdio> #include <iostream> #include &l

【图论】

2-sat总结 2-sat问题,一般表现的形式为,每个点有两种方式a,b,要么选a,要么选b,并且点点之间有一些约束关系,例如:u和v至少一个选a,那么这就是一个表达式,把a当成真,b当成假,那就是u真或v真,2-sat的题目就是这样,给定这些约束,判断是否会矛盾 注意表达式的转化形式,(其实就是离散数学中那几种转换方式) 比如(u真且v真)或(u假且v假)就可以转化成(u真或v假)且(u假或v真),这样就能建立关系 2-sat中的原理,其实和2染色是一样的,把每个结点拆分成一个真结点和一个假结