poj 3256 Cow Picnic dfs

题意:有k头牛n个农场面条有向边(拓扑有序,不存在环),告诉你所有奶牛的初始位置,求所有奶牛能够到达的公共点。

记录每头奶牛能够到达的位子,最后判断一下就可以了。

View Code
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
#define re(i,n) for(int i=0;i<n;i++)
#define re1(i,n) for(int i=1;i<=n;i++)
const int maxn = 1010 , maxm = 10010;
int k , n , m;
struct Edge{ int v ,next; }edge[maxm];
int E,head[maxn];
inline void init() { E = 0;memset(head,-1,sizeof(head)); }
inline void addedge(int u,int v) { edge[E].v=v;edge[E].next=head[u];head[u]=E++; }
bool live[maxn]; // there lives a cow in farm i
bool vis[maxn][maxn]; // cow i can visit farm j
void dfs(int c , int u) {
    if(vis[c][u]) return;
    vis[c][u] = true;
    for(int i=head[u];i!=-1;i=edge[i].next) {
        int v = edge[i].v;
        if(!vis[c][v]) dfs(c , v);
    }
}
int main() {
    while(~scanf("%d%d%d",&k,&n,&m)) {
        memset(live,0,sizeof(live));
        memset(vis,0,sizeof(vis));
        init();
        re(i,k) {
            int t;
            scanf("%d",&t);
            live[t] = true;
        }
        re(i,m) {
            int u , v;
            scanf("%d%d",&u,&v);
            if(live[u] && live[v]) live[u] = false;
            addedge(u,v);
        }
        re1(i,n) if(live[i]) dfs(i,i);
        int cnt = 0;
        re1(i,n) re1(j,n) if(live[j] && !vis[j][i]) { cnt++;break;  }
        printf("%d\n",n-cnt);
    }
    return 0;
}
posted @ 2012-07-02 02:47  lenohoo  阅读(125)  评论(0编辑  收藏  举报