题解 P2419 [USACO08JAN]牛大赛Cow Contest
Posted lixiao189
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解 P2419 [USACO08JAN]牛大赛Cow Contest相关的知识,希望对你有一定的参考价值。
看到许多大佬都用了拓补排序,本蒟蒻偏不用这么高级的算法,其实这道题目用dfs就可以过了。(ps:对本题解有疑惑的person可以向我留下评论)
思路:
我们先来考虑一下怎么样我们才可以确定一个牛的排名,我们如果假设赢了或间接赢了这个牛的牛数为sum_win,输了或间接输掉的牛数为sum_lose,如果要确认一个牛的排名,很显然当且仅当满足一下情况的时候才能确定一个牛的排名。
sum_win+sum_lose==n-1
接下来这样的问题就转换为了如何求sum_win与sum_lose。
我们用两个图用来存这道题目中的输赢关系,其中第一个图我们用一个结点指向另一个结点表示一头牛输给了别人,另外一个图恰好相反。这样我们从1~n枚举结点i,从一个结点i开始dfs一遍第一个图,sum_win就是遍历到的结点数,这样也很完美地解决了间接赢了别人如何处理的问题,之后我们再遍历第二个图,累计遍历到的点,得到sum_lose
之后判断一下上面给出的条件即可得到第i个结点即牛是否满足条件
代码:
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e2+5;
int n,m;
int vis_win[N];
int vis_lose[N];
int sum_win,sum_lose;
vector <int> win_graph[N];
vector <int> lose_graph[N];
void add(int x,int y){ //x为胜者
win_graph[y].push_back(x);
lose_graph[x].push_back(y);
}
void dfs_win(int x){
vector <int> :: iterator it;
for(it=win_graph[x].begin();it!=win_graph[x].end();it++){
if(vis_win[*it]==0){
sum_win++;
vis_win[*it]=1;
dfs_win(*it);
}
}
}
void dfs_lose(int x){
vector <int> :: iterator it;
for(it=lose_graph[x].begin();it!=lose_graph[x].end();it++){
if(vis_lose[*it]==0){
sum_lose++;
vis_lose[*it]=1;
dfs_lose(*it);
}
}
}
int main(){
scanf("%d%d",&n,&m);
int temp_x,temp_y;
for(int i=1;i<=m;i++){
scanf("%d%d",&temp_x,&temp_y);
add(temp_x,temp_y);
}
int ans=0;
for(int i=1;i<=n;i++){
memset(vis_win,0,sizeof(vis_win));
memset(vis_lose,0,sizeof(vis_lose));
sum_win=0;sum_lose=0;
dfs_win(i);
dfs_lose(i);
if(sum_win+sum_lose==n-1) ans++;
}
printf("%d
",ans);
return 0;
}
以上是关于题解 P2419 [USACO08JAN]牛大赛Cow Contest的主要内容,如果未能解决你的问题,请参考以下文章
P2419 [USACO08JAN]牛大赛Cow Contest
bzoj1612 / P2419 [USACO08JAN]牛大赛Cow Contest(Floyd)
Luogu P2419 [USACO08JAN]牛大赛Cow Contest