• 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;
        }
    }
    only strive for your goal , can you make your dream come true ?
  • 相关阅读:
    插入排序实现
    冒泡排序的实现
    选择排序的实现方法
    实现文字的竖排
    一个实体类的定义
    将字符串中的非字母数字,转化为ascii码输出
    根据员工入职时间和合同期计算下一次合同签订时间
    centos安装java的问题解决
    弓箭射小人
    Nature & Science 20102011年全部期刊下载链接
  • 原文地址:https://www.cnblogs.com/hlmark/p/4019339.html
Copyright © 2020-2023  润新知