poj 1227 RoboContest

http://poj.org/problem?id=1227

题意:给一个无向图,然后在图中的一些点放置一些机器人,机器人在每一秒中都要向相邻的方向走去。问是否存在在某个时刻,每个机器人都在一个点上。

思路:利用奇偶性解决,如果图中存在一下奇数环,则一定满足;不然看某个到到达所以机器人的步数的奇偶性是否一样就可以了。

View Code
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<cmath>
#include<bitset>
#include<string>
#include<climits>
#include<cstdio>
#include<vector>
#include<utility>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define IN puts("in")
#define OUT puts("out")
#define FR(x) freopen(x,"r",stdin)
#define FW(x) freopen(x,"w",stdout)
#define MSET(x,y) memset(x,y,sizeof(x))
#define ST system("pause")
using namespace std;

const int maxn = 105;

struct nd
{
        int u,v,next;
}edge[maxn*maxn];
int head[maxn],vis[maxn],dfn[maxn],low[maxn],st[maxn],as[maxn],flag[maxn],bs[maxn][maxn],belg[maxn],color[maxn],cs[maxn];
int ecnt,cnt,idx,tp,ok;
void add(int u,int v)
{
        edge[ecnt].u = u;
        edge[ecnt].v = v;
        edge[ecnt].next = head[u];
        head[u] = ecnt++;
}
int judge(int u,int f)
{
        int i,v;
        color[u] = f;
        for(i = head[u]; i != -1; i = edge[i].next)
        {
                v = edge[i].v;
                if(belg[v]==cnt)
                {
                        if(color[v]==color[u])return 1;
                        if(!color[v]&&judge(v,-f))return 1;
                }
        }
        return 0;
}
void tarjan(int pre,int u)
{
        int i,v,t,k,j;
        dfn[u] = low[u] = ++idx;
        vis[u] = 1;
        st[++tp] = u;
        for(i = head[u]; i != -1; i = edge[i].next)
        {
                v = edge[i].v;
                if(v==pre)continue;
                if(!dfn[v]){
                        tarjan(u,v);
                        low[u] = min(low[v],low[u]);
                        if(low[v]>=dfn[u]){
                                k = t = 0;
                                cnt++;
                                do{
                                        j = st[tp--];
                                        as[++k] = j;
                                        belg[j] = cnt;
                                        vis[j] = 0;
                                }while(v!=j);
                                as[++k] = u;
                                MSET(color,0);
                                if(k>=3&&judge(u,1)){
                                        ok = 1;
                                }
                        }
                }else if(vis[v])low[u] = min(dfn[v],low[u]);
        }
}
void dfs(int pre,int u,int sum)
{
        int i,v;
        vis[u] = sum;
        for(i = head[u]; i != -1; i = edge[i].next)
        {
                v = edge[i].v;
                if(v==pre||vis[v])continue;
                dfs(u,v,sum+1);
        }
}
void processing(int n,int m)
{
        int i,j,k=0,u,v,t;
        map<int,int>mmap;
        for(i = 0; i < n; ++ i)
        {
                scanf("%d %d",&u,&t);
                if(mmap.find(u)==mmap.end()) mmap[u] = ++k;
                u = mmap[u];
                while(t--){
                        scanf("%d",&v);
                        if(mmap.find(v)==mmap.end())mmap[v] = ++k;
                        v = mmap[v];
                        bs[u][v] = 0;
                }
        }
        for(i = 1; i <= m; ++ i){
                scanf("%d",&u);
                if(mmap.find(u)==mmap.end()) mmap[u] = ++k;
                cs[i] = mmap[u];
        }
        for(i = 1; i <= n; ++ i)
                for(j = 1; j <= n; ++ j)
                        if(!bs[i][j]) add(i,j);
        ok = 0;
        for(i = 1; i <= n; ++ i){
                if(!dfn[i])tarjan(-1,i);
                for(j = 1; j <= n; ++ j)if(!dfn[j]){
                        for(k = 1; k <= m; ++ k)
                        if(cs[k]==j){puts("NO"); return ;}
                }
        }
        if(ok||n==1)puts("YES");
        else{
                for(i = 1; i <= n; ++ i)
                {
                        MSET(vis,0);
                        dfs(-1,i,0);
                        k = vis[cs[1]]&1;
                        for(j = 2; j <= m; ++ j)
                                if((vis[cs[j]]&1)!=k)break;
                        if(j>m)ok=1;
                }
                if(ok)puts("YES");
                else puts("NO");
        }
}
void init()
{
        ecnt = cnt = idx = tp = 0;
        MSET(head,-1);
        MSET(vis,0);
        MSET(dfn,0);
        MSET(flag,-1);
        MSET(bs,-1);
        MSET(belg,-1);
}
int main()
{
        int n,m,t;
        scanf("%d",&t);
        while(t--)
        {
                scanf("%d %d",&n,&m);
                init();
                processing(n,m);
        }
        return 0;
}

posted on 2012-07-18 16:55  aigoruan  阅读(222)  评论(0)    收藏  举报

导航