pku 1227 RoboContest 奇环判断(黑白染色)

题意是这样,有一个无向图,在其中的k个点上有机器人,在每个时刻,机器人移动至与当前节点邻接的任意一个节点。问有没有可能在某个时刻所有的机器人移动到一个节点上。
我的思路是这样的:
在图连通的情况下如果图中有奇圈,那么任意一个机器人都能够在偶数步和奇数步内到达任意一个节点,如果所有的机器人都能在偶数步或者奇数步里到达某个节点,那么就成立。因为图中肯定有2圈,所以先到的机器人总可以用“来回走”的形式等后面的机器人。
这样,算法就成型了:
1、判断机器人所在的节点是否连通
2、判断图中是否有奇圈(二分图的定义,只需黑白染色即可判断)
3、如果有奇圈,则输出YES,否则,这个图就是一个二分图,所有的机器人都能在偶数步或者奇数步里到达某个节点当且仅当所有的机器人都在同一类节点中。
还有点细节就是编号可能不是1,2,3..N这样编的,所以要先hash处理下(我偷懒,直接用STL MAP了)
贴代码
  1 # include <cstdio>
  2 using namespace std;
  3 # define N 105
  4 # include <vector>
  5 # include <cstring>
  6 # include <map>
  7 # include <queue>
  8 vector<int> g[N];
  9 int color[N];
 10 int n,k,c;
 11 map<int,int> refer;
 12 vector<int> ins[N];
 13 vector<int> target;
 14 bool make_color()
 15 {
 16    queue<int> q;
 17    memset(color,-1,sizeof(color));
 18    q.push(target[0]);
 19    color[target[0]]=0;
 20    while(!q.empty())
 21    {
 22      int top=q.front(),c=(color[top]?0:1);
 23      q.pop();
 24      for(int i=0;i<g[top].size();i++)
 25        if(color[g[top][i]]==-1)
 26        {
 27           color[g[top][i]]=c;
 28           q.push(g[top][i]);
 29        }
 30        else if(color[g[top][i]]==color[top])
 31          return false;
 32    }
 33    return true;
 34 }
 35 bool connect()
 36 {
 37    queue<int> q;
 38    memset(color,-1,sizeof(color));
 39    q.push(target[0]);
 40    color[target[0]]=0;
 41    while(!q.empty())
 42    {
 43      int top=q.front();
 44      q.pop();
 45      for(int i=0;i<g[top].size();i++)
 46        if(color[g[top][i]]==-1)
 47        {
 48           color[g[top][i]]=0;
 49           q.push(g[top][i]);
 50        }
 51    }
 52    for(int i=0;i<target.size();i++)
 53      if(color[target[i]]==-1)
 54        return false;
 55    return true;
 56 }
 57 int main()
 58 {
 59     int testcase;
 60     scanf("%d",&testcase);
 61     while(testcase--)
 62     {
 63         c=0;
 64         refer.clear();
 65         scanf("%d%d",&n,&k);
 66         for(int i=0;i<n;i++)
 67         {
 68           ins[i].clear();
 69           int id,num;
 70           scanf("%d%d",&id,&num);
 71           while(num--)
 72           {
 73              int t;
 74              scanf("%d",&t);
 75              ins[i].push_back(t);
 76           }
 77           refer[id]=c++;
 78         }
 79         for(int i=0;i<n;i++)
 80         {
 81            g[i].clear();
 82            for(int j=0;j<ins[i].size();j++)
 83              g[i].push_back(refer[ins[i][j]]);
 84         }
 85         target.clear();
 86         while(k--)
 87         {
 88            int t;
 89            scanf("%d",&t);
 90            target.push_back(refer[t]);
 91         }
 92         if(!connect())
 93           printf("NO\n");
 94         else if(!make_color())
 95            printf("YES\n");
 96         else
 97         {
 98             bool flag=true;
 99             for(int i=1;i<target.size()&&flag;i++)
100               if(color[target[i]]!=color[target[i-1]])
101                 flag=false;
102             if(flag) printf("YES\n");
103             else printf("NO\n");
104         }        
105     }
106     return 0;
107 }
108 


posted on 2010-11-05 13:21 yzhw 阅读(332) 评论(0)  编辑 收藏 引用 所属分类: graph


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2010年11月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

导航

统计

公告

统计系统

留言簿(1)

随笔分类(227)

文章分类(2)

OJ

最新随笔

搜索

积分与排名

最新评论

阅读排行榜