1. 程式人生 > >COGS [USACO Mar07] 奶牛交通

COGS [USACO Mar07] 奶牛交通

int node opened char col sum pri 道路 ont

[USACO Mar07] 奶牛交通

農場中,由於奶牛數量的迅速增長,通往奶牛宿舍的道路也出現了嚴重的交通擁堵問題.FJ打算找出最忙碌的道路來重點整治.

這個牧區包括一個由M (1 ≤ M ≤ 50,000)條單行道路(有向)組成的網絡,以及 N (1 ≤ N ≤ 5,000)個交叉路口(編號為1..N),每一條道路連接兩個不同的交叉路口.奶牛宿舍位於第N個路口.每一條道路都由編號較小的路口通向編號較大的路 口.這樣就可以避免網絡中出現環.顯而易見,所有道路都通向奶牛宿舍.而兩個交叉路口可能由不止一條邊連接.

在準備睡覺的時候,所有奶牛都從他們各自所在的交叉路口走向奶牛宿舍,奶牛只會在入度為0的路口,且所有入度為0的路口都會有奶牛.

幫助FJ找出最忙碌的道路,即計算所有路徑中通過某條道路的最大次數.答案保證可以用32位整數存儲.


輸入格式:

  • 第一行:兩個用空格隔開的整數:N,M.
  • 第二行到第M+1行:每行兩個用空格隔開的整數ai,bi,表示一條道路從ai到bi.


輸出格式:

  • 第一行: 一個整數,表示所有路徑中通過某條道路的最大次數.

樣例輸入:

7 7
1 3
3 4
3 5
4 6
2 3
5 6
6 7

樣例輸出

4

樣例說明:

    1   4
     \ /       3   6 -- 7
     / \ /
    2   5

通向奶牛宿舍的所有路徑:

    1 3 4 6 7
    1 3 5 6 7
    2 3 4 6 7
    2 3 5 6 7


通過某一條路的次數就是通過某一條路兩端點路徑條數的乘積
f[i]代表從一個入度為0的點到f[i]的路徑條數
g[i]代表從n到i點的路徑條數

f[i]=Sum{ f[j] } 存在邊(j,i)
g[i]=Sum{ g[j] } 存在邊(i,j)

f[k]=1 k為入度為0的點
g[n]=1;
ans=Max{ f[a]*g[b] } 存在邊(a,b)

技術分享
 1 #include <cctype>
 2 #include <cstdio>
 3 
 4 const int MAXN=5010;
 5 
 6 int n,m;
 7 
 8 int f[MAXN],g[MAXN];
 9 
10 struct node {
11     int to;
12     int next;
13     node() {}
14     node(int to,int next):to(to),next(next) {}
15 };
16 node e[MAXN*10],r[MAXN*10];
17 
18 int head[MAXN],Head[MAXN],tot;
19 
20 inline void read(int&x) {
21     int f=1;register char c=getchar();
22     for(x=0;!isdigit(c);c==-&&(f=-1),c=getchar());
23     for(;isdigit(c);x=x*10+c-48,c=getchar());
24     x=x*f;
25 }
26 
27 inline int max(int a,int b) {return a<b?b:a;}
28 
29 inline void add(int x,int y) {
30     e[++tot]=node(y,head[x]);
31     head[x]=tot;
32     r[tot]=node(x,Head[y]);
33     Head[y]=tot;
34 }
35 
36 int hh() {
37     freopen("cowtraffic.in","r",stdin);
38     freopen("cowtraffic.out","w",stdout);
39     read(n);read(m);
40     int x,y;
41     for(register int i=1;i<=m;++i) {
42         read(x);read(y);
43         add(x,y);
44         if(x>y) x^=y^=x^=y;//其實沒必要 
45     }
46     g[n]=1;
47     for(register int i=1;i<=n;++i) 
48       if(!Head[i]) f[i]=1;
49       
50     for(register int i=1;i<=n;++i)
51       for(register int j=head[i];j;j=e[j].next)
52         f[e[j].to]+=f[i];
53         
54     for(register int i=n;i>=1;--i) 
55       for(register int j=Head[i];j;j=r[j].next)
56         g[r[j].to]+=g[i]; 
57         
58     int ans=-1;
59     for(register int i=1;i<=n;++i) 
60       for(register int j=head[i];j;j=e[j].next)
61         ans=max(ans,f[i]*g[e[j].to]);
62     printf("%d\n",ans);
63     return 0;
64 }
65 
66 int sb=hh();
67 int main(int argc,char**argv) {;}
代碼

 

COGS [USACO Mar07] 奶牛交通