cdoj 916-方先生の分身III【位相配列】
9511 ワード
http://acm.uestc.edu.cn/#/problem/show/916
方先生の分身III
Time Limit:3000/1000 MS(Java/Others) メモリLimit:65535/65535 KB(Java/Others)
Submit
Status
一日の講座が終わると、方先生の分身たちが集まった。一つの先生になる前に。これらの分身は方先生の真身にあめを出すように要求します。これらの分身は方先生に少なくとも888個の砂糖を送ってもらいます。これはまだ足りないです。ある分身は他の分身の糖より多いです。先生は砂糖を最低何点に分けますか?
Input
複数のデータがあります
最初の行の2つの整数N(1≦N≦10000)、M(0≦M≦20000)は分身数と要求数を表します。
次のm行は、1行につき2つの整数x,yです。xはyよりも多くのキャンディを要求します。
Output
つの整数、方の先生は少なくともどれだけの砂糖に分けます。分糖出力−1が完了できない場合。
Sample input and output
Sample Input
Sample Output
トポロジーの順序は容易に考えられます。テーマの中で環を設計して、位相の順序付けで環の存在を判断することができます。また,トポロジーの方向に注意が必要である。
コード:
方先生の分身III
Time Limit:3000/1000 MS(Java/Others) メモリLimit:65535/65535 KB(Java/Others)
Submit
Status
一日の講座が終わると、方先生の分身たちが集まった。一つの先生になる前に。これらの分身は方先生の真身にあめを出すように要求します。これらの分身は方先生に少なくとも888個の砂糖を送ってもらいます。これはまだ足りないです。ある分身は他の分身の糖より多いです。先生は砂糖を最低何点に分けますか?
Input
複数のデータがあります
最初の行の2つの整数N(1≦N≦10000)、M(0≦M≦20000)は分身数と要求数を表します。
次のm行は、1行につき2つの整数x,yです。xはyよりも多くのキャンディを要求します。
Output
つの整数、方の先生は少なくともどれだけの砂糖に分けます。分糖出力−1が完了できない場合。
Sample input and output
Sample Input
Sample Output
2 1
1 2
2 2
1 2
2 1
1777
-1
トポロジーの順序は容易に考えられます。テーマの中で環を設計して、位相の順序付けで環の存在を判断することができます。また,トポロジーの方向に注意が必要である。
コード:
1 #include <fstream>
2 #include <iostream>
3 #include <cstdio>
4 #include <cstring>
5
6 using namespace std;
7
8 const int cnt=888;
9 const int N=10005;
10 const int M=20005;
11 int n,m;
12 int u[M],v[M],head[N],la[M];
13 int du[N],cn[N];
14 bool b;
15
16 void topology();
17
18 int main()
19 {
20 //freopen("D:\\input.in","r",stdin);
21 //freopen("D:\\output.out","w",stdout);
22 while(~scanf("%d%d",&n,&m)){
23 memset(head,-1,sizeof(head));
24 memset(du,0,sizeof(du));
25 memset(cn,0,sizeof(cn));
26 for(int i=0;i<m;i++){
27 scanf("%d%d",&v[i],&u[i]);
28 la[i]=head[u[i]];
29 head[u[i]]=i;
30 du[v[i]]++;
31 }
32 b=true;
33 topology();
34 if(b){
35 int ans=cnt*n;
36 for(int i=1;i<=n;i++){
37 ans+=cn[i];
38 }
39 printf("%d
",ans);
40 }else{
41 puts("-1");
42 }
43 }
44 return 0;
45 }
46 void topology(){
47 int top=-1;
48 for(int i=1;i<=n;i++)
49 if(!du[i]) du[i]=top,top=i;
50 for(int i=0;i<n;i++){
51 if(top==-1){
52 b=false;
53 return;
54 }else{
55 int j=top;
56 top=du[top];
57 for(int k=head[j];k!=-1;k=la[k]){
58 cn[v[k]]=max(cn[v[k]],cn[j]+1);
59 if(!(--du[v[k]])) du[v[k]]=top,top=v[k];
60 }
61 }
62 }
63 }