山上的国度
P1394
题目描述
有一个神秘的小国坐落在南方的青山之上,只有当黄昏时,落日耀眼的余晖刺破薄雾的遮拦,有机缘者才可看到小山上面的n个美丽的村庄。
传说这个古老的国家里有m条枢纽管道,每一条苍老的管道连接着两个村庄,千百年来为村民提供水源的流通。
n个村庄里只有一个水库,从有水库的村庄通过这些枢纽管道向其它村庄提供水源。大家都明白水往低处流,所有村庄都能得到水库的供水。
黄小明就是那个有机缘者,同时他也是个偏执狂(把小猫绑在一起的那个变态小明),他迫切的想要知道水库应该在哪一个村庄,你能帮他解决疑惑吗?
输入输出格式
输入格式:
第一行输入n,m<=300。第二行输入n个正整数,第i个数表示第i个村庄的海拔。之后m行每行两个数表示这两个村庄之间有一条道路。(同海拔之间不能相互流水)
输出格式:
若存在这样的村庄,输出两行:
第一行为“Oui, j’ai trouve la solution.”。
第二行为村庄的编号。
若不行,请输出“Non”(不包括引号,可参见样例)
输入输出样例
输入样例#1:
4 2
1 2 3 4
1 2
3 4
输出样例#1:
Non
思路
这个题比较自然的思想就是,我们将管道两端高度更高的一边作为出发点,另一个就是到达点,那么到达点的入度+1。入度如果不是0,那么就说明它没有来源,反之有来源,那么它必须有水源,而水源只有一个,所以这张图的所有点来源入度为0的只有1个的时候才有解,然后输出入度为0的那个点,反之无解。
不过Luogu上面数据#18有错误,无伤大雅。
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
using namespace std;
int i,j,n,m,temp;
int p[301],v[301],rd[301],hd[301];
int b[301];
struct data
{
int v,nxt;
}a[601];
int r()
{
int ans=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
ans*=10;
ans+=ch-'0';
ch=getchar();
}
return ans*f;
}
int ans;
void add(int x,int y)
{
a[++temp].v=y;
a[temp].nxt=hd[x];
hd[x]=temp;
}
int main()
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
n=r();m=r();
for(i=1;i<=n;i++)
{
v[i]=r();
}
int xx,yy,num=n;
for(i=1;i<=m;i++)
{
xx=r(),yy=r();
if(v[xx]>v[yy])
{
if(!rd[yy])
num--;
rd[yy]++;
b[yy]=1;
}
else if(v[xx]<v[yy])
{
if(!rd[xx])
num--;
rd[xx]++;
b[xx]=1;
}
}
if(num==1)
{
for(i=1;i<=n;i++)
{
if(!b[i])
cout<<"Oui, j'ai trouve la solution."<<endl<<i;
}
}
else
cout<<"Non";
return 0;
}
/*min(f[j],f[i-1][j-k*p[i]]+c[i]*k);
4 3
1 2 3 4
1 2
2 3
3 4
*/