n个点m条有向边,求在入度为零的点到n号点的所有路 //径中,哪条边被这些路径覆盖的次数最多

 1 //n个点m条有向边,求在入度为零的点到n号点的所有路
 2 //径中,哪条边被这些路径覆盖的次数最多
 3 //有关DAG的知识,先记个模板
 4 #include<iostream>
 5 #include<cstdio>
 6 #include<cstring>
 7 #include<algorithm>
 8 using namespace std;
 9 typedef long long ll;
10 const int maxn=5e3+10;
11 const int maxm=5e4+10;
12 struct node
13 {
14     int v;
15     int next;
16     ll cnt;
17 }edge[maxm],Edge[maxm];
18 int head[maxn];
19 int HEAD[maxn];
20 int cnt;
21 ll f[maxn],g[maxn];
22 int id[maxn],od[maxn];
23 void add(int u,int v)
24 {
25     ++cnt;
26     edge[cnt].v=v;
27     edge[cnt].next=head[u];
28     head[u]=cnt;
29     Edge[cnt].v=u;
30     Edge[cnt].next=HEAD[v];
31     HEAD[v]=cnt;
32 }
33 int main()
34 {
35     int i,j,n,m,v;
36     scanf("%d%d",&n,&m);
37     int a,b;
38     for( i=1;i<=m;i++){
39         scanf("%d%d",&a,&b);
40         add(a,b);
41         id[b]++; od[a]++;
42     }
43     for(int i=1;i<=n;i++){
44        if(!id[i]) f[i]=1;
45        if(!od[i]) g[i]=1;
46     }
47     for(i=1;i<=n;i++){
48        for(j=head[i];j;j=edge[j].next){
49            v=edge[j].v;
50            f[v]+=f[i];
51            edge[j].cnt+=f[i];
52        }
53     }
54     for(j=n;j>=1;j--){
55        for(i=HEAD[j];i;i=Edge[i].next){
56            v=Edge[i].v;
57            g[v]+=g[j];
58            Edge[i].cnt+=g[j];
59        }
60     }
61     ll ans=0;
62     for(i=1;i<=m;i++)
63         ans=max(ans,edge[i].cnt*Edge[i].cnt);
64     printf("%lld\n",ans);
65     return 0;
66 }

 

posted @ 2019-10-28 22:07  古比  阅读(163)  评论(0编辑  收藏  举报