[kuangbin带你飞]专题四 最短路练习 H POJ 3660

时间:2023-02-13 18:36:03

题目地址:https://vjudge.net/contest/66569#problem/H

思路:如果一头牛的位置可以确定,那么他必然与其他所有牛联通。所以我对于战胜的情况建了个图,对于战败的情况另建一张图,各跑一次spfa,如果能到达所有点,则说明位置确定。不过感觉这样效率好低,写完看了下 Discuss貌似可以用Floyd,话说这个题目是不是应该也能用拓扑?

AC代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
int degree[105];
vector<pair<int,int> >E[105];
vector<pair<int,int> >E1[105];
int d[105];
int n,m;

void spfa(int s)
{
int in[105];
bool vis[105];
for(int i=1;i<105;i++)
{
d[i]=0x3f3f3f3f;
in[i]=0;
vis[i]=false;
}
d[s]=0;
vis[s]=true;
queue<int>q;
q.push(s);
while(!q.empty())
{
int now=q.front();
q.pop();
vis[now]=false;
if(in[now]++>n)
return;
for(int i=0;i<E[now].size();i++)
{
int v=E[now][i].first;
if(d[v]>d[now]+1)
{
d[v]=d[now]+1;
if(!vis[v])
{
q.push(v);
vis[v]=true;
}
}
}

}

}

void spfa1(int s)
{
int in[105];
bool vis[105];
for(int i=1;i<105;i++)
{
d[i]=0x3f3f3f3f;
in[i]=0;
vis[i]=false;
}
d[s]=0;
vis[s]=true;
queue<int>q;
q.push(s);
while(!q.empty())
{
int now=q.front();
q.pop();
vis[now]=false;
if(in[now]++>n)
return;
for(int i=0;i<E1[now].size();i++)
{
int v=E1[now][i].first;
if(d[v]>d[now]+1)
{
d[v]=d[now]+1;
if(!vis[v])
{
q.push(v);
vis[v]=true;
}
}
}

}

}

int main()
{

scanf("%d%d",&n,&m);
for(int i=0;i<m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
E[a].push_back(make_pair(b,1));
E1[b].push_back(make_pair(a,1));
}
int ans=0;
for(int i=1;i<=n;i++)
{
int y[105];
memset(y,0,sizeof(y));
spfa(i);
for(int j=1;j<=n;j++)
{
if(d[j]!=0x3f3f3f3f)
y[j]=1;
}
spfa1(i);
for(int j=1;j<=n;j++)
{
if(d[j]!=0x3f3f3f3f)
y[j]=1;
}
int temp=1;
for(int j=1;j<=n;j++)
{
if(!y[j])
{
temp=0;
break;
}

}
if(temp)
ans++;
}
printf("%d\n",ans);
}