USACO 4.3 Street Race (搜索)

2015-03-26 20:55:52

思路:题目大意是给出一个有向图,给出起点和终点,让你求出两种点:

  (1)任何从起点->终点的路径都必须经过的点。(2)该点将图分为两部分,(起点->该点)和(该点->终点)两个部分,且两个部分没有边相连。

  考虑:显然(2)点必然是(1)点,所以我们先求(1)点,方法很简单,枚举删除每个点,如果删除后从起点出发走不到终点了,那么该点符合(1)的性质。

       这个过程从起点floodfill(bfs)可以实现。求(2)点稍微复杂点,也是枚举每个点,假设按照这个点来分割图,显然该点出边对应的另一些点V1,入边对应的

       另一些点V2分别属于两个部分,那么我们就可以从点集V2出发floodfill(bfs),把遍历到的点标记掉,最后判断是否有点集V1里的点被标记掉。需要注意的是:

     此时应该把图看做无向图来做,我们需要判断的是两个部分是否有边相连,而不是两个有向子图是否连通(思考)。

  1 /*
  2 ID:naturec1
  3 PROG: race3
  4 LANG: C++
  5 */
  6 #include <cstdio>
  7 #include <cstring>
  8 #include <cstdlib>
  9 #include <cmath>
 10 #include <vector>
 11 #include <map>
 12 #include <set>
 13 #include <stack>
 14 #include <queue>
 15 #include <string>
 16 #include <iostream>
 17 #include <algorithm>
 18 using namespace std;
 19 
 20 #define MEM(a,b) memset(a,b,sizeof(a))
 21 #define REP(i,n) for(int i=1;i<=(n);++i)
 22 #define REV(i,n) for(int i=(n);i>=1;--i)
 23 #define FOR(i,a,b) for(int i=(a);i<=(b);++i)
 24 #define RFOR(i,a,b) for(int i=(a);i>=(b);--i)
 25 #define getmid(l,r) ((l) + ((r) - (l)) / 2)
 26 #define MP(a,b) make_pair(a,b)
 27 
 28 typedef long long ll;
 29 typedef pair<int,int> pii;
 30 const int INF = (1 << 30) - 1;
 31 const int MAXN = 210;
 32 
 33 int g[MAXN][MAXN];
 34 int vis[MAXN],st,ed;
 35 vector<int> ans1,ans2;
 36 
 37 bool Check1(int p){
 38     queue<int> Q;
 39     while(!Q.empty()) Q.pop();
 40     Q.push(st);
 41     MEM(vis,0);
 42     vis[st] = 1;
 43     while(!Q.empty()){
 44         int x = Q.front(); Q.pop();
 45         for(int i = st + 1; i <= ed; ++i) if(g[x][i]){
 46             if(i == p) continue;
 47             if(!vis[i]){
 48                 vis[i] = 1;
 49                 Q.push(i);
 50             }
 51         }
 52     }
 53     return vis[ed] == 0;
 54 }
 55 
 56 int fa[MAXN];
 57 
 58 bool Check2(int p){
 59     queue<int> Q;
 60     while(!Q.empty()) Q.pop();
 61     MEM(vis,0);
 62     vis[p] = 1;
 63     for(int i = st; i <= ed; ++i) if(!vis[i] && g[p][i]){
 64         vis[i] = 1;
 65         Q.push(i);
 66     }
 67     while(!Q.empty()){
 68         int x = Q.front(); Q.pop();
 69         for(int i = st; i <= ed; ++i) if(g[x][i] || g[i][x]){
 70             if(i == p) continue;
 71             if(!vis[i]){
 72                 vis[i] = 1;
 73                 Q.push(i);
 74             }
 75         }
 76     }
 77     for(int i = st; i <= ed; ++i) if(vis[i] == 0) return true;
 78     return false;
 79 }
 80 
 81 int main(){
 82     freopen("race3.in","r",stdin);
 83     freopen("race3.out","w",stdout);
 84     int tot = 0;
 85     int a,b;
 86     while(scanf("%d",&a) != EOF){
 87         if(a == -1) break;
 88         if(a == -2){
 89             tot++;
 90             continue;
 91         }
 92         g[tot][a] = 1;
 93         while(cin >> a && a != -2) g[tot][a] = 1;
 94         tot++;
 95     }
 96     st = 0;
 97     ed = tot - 1;
 98     REP(i,ed - 1){
 99         if(Check1(i)){
100             ans1.push_back(i);
101             if(Check2(i)) ans2.push_back(i);
102         }
103     }
104     printf("%d",(int)ans1.size());
105     for(int i = 0; i < ans1.size(); ++i) printf(" %d",ans1[i]);
106     puts("");
107     printf("%d",(int)ans2.size());
108     for(int i = 0; i < ans2.size(); ++i) printf(" %d",ans2[i]);
109     puts("");
110     return 0;
111 }

 

posted @ 2015-03-26 21:11  Naturain  阅读(220)  评论(0编辑  收藏  举报