山上的國度
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
*/