HDU3549 最大流 裸题

EK算法 时间复杂度o(n*m*m)  因为有反向边每次bfs时间为 n*m 每次删一条边 最多m次

 代码

 1 #include<iostream>
 2 #include<string.h>
 3 #include<vector>
 4 #include<stdio.h>
 5 #include<queue>
 6 using namespace std;
 7 const int maxn=2e5+10,inf=0x3f3f3f3f;
 8 typedef long long ll;
 9 struct edge
10 {
11     int from,to,c,f;
12     edge(int u,int v,int c,int f):from(u),to(v),c(c),f(f) {}
13 };
14 int n,m;
15 vector<edge> edges;
16 vector<int> g[maxn];
17 int a[maxn],p[maxn];
18 void init()
19 {
20     for(int i=0; i<=n; i++) g[i].clear();
21     edges.clear();
22 }
23 void addedge(int from,int to,int c)
24 {
25     edges.push_back(edge(from,to,c,0));
26     edges.push_back(edge(to,from,0,0));
27     int siz=edges.size();
28     g[from].push_back(siz-2);
29     g[to].push_back(siz-1);
30 }
31 ll maxflow(int s,int t)
32 {
33     ll flow=0;
34     while(1)
35     {
36         memset(a,0,sizeof(a));
37         queue<int> q;
38         q.push(s);
39         a[s]=inf;
40         while(!q.empty())
41         {
42             int x=q.front();
43             q.pop();
44             //  cout<<x<<" "<<g[x].size()<<endl;
45             for(int i=0; i<g[x].size(); i++)
46             {
47                 int u=g[x][i];
48                 edge &e=edges[u];
49                 //cout<<e.from<<" "<<e.to<<endl;
50                 if(!a[e.to]&&e.c>e.f)
51                 {
52                     p[e.to]=u; //存边
53                     a[e.to]=min(a[x],e.c-e.f);
54                     q.push(e.to);
55                 }
56             }
57             if(a[t])break;
58         }
59         // cout<<a[t]<<endl;                   //a[t]为一次增广值
60         if(!a[t]) break;
61         for(int u=t; u!=s; u=edges[p[u]].from)//流量修改
62         {
63             edges[p[u]].f+=a[t];
64             edges[p[u]^1].f-=a[t];
65         }
66         flow+=(ll)a[t];
67     }
68     return flow;
69 }
70 int main()
71 {
72     int t,u,v,c,f,kase=1;
73     cin>>t;
74     while(t--)
75     {
76         cin>>n>>m;
77         init();
78         for(int i=0; i<m; i++)
79         {
80             cin>>u>>v>>c;
81             addedge(u-1,v-1,c);
82         }
83         printf("Case %d: %d\n",kase++,maxflow(0,n-1));
84         //cout<<maxflow(0,n-1)<<endl;
85     }
86 }

Dinic  时间复杂度o(n*n*m)最多计算n-1次阻塞流 每次n*m  很松的上界

代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e3+20,mod=1e9+7,inf=0x3f3f3f3f;
 4 typedef long long ll;
 5 struct edge
 6 {
 7     int from,to,c,f;
 8     edge(int u,int v,int c,int f):from(u),to(v),c(c),f(f) {}
 9 };
10 int n,m;
11 vector<edge> edges;
12 vector<int> g[maxn];
13 int d[maxn];//从起点到i的距离
14 int cur[maxn];//当前弧下标
15 void init()
16 {
17     for(int i=0; i<=n; i++) g[i].clear();
18     edges.clear();
19 }
20 void addedge(int from,int to,int c) //加边 支持重边
21 {
22     edges.push_back(edge(from,to,c,0));
23     edges.push_back(edge(to,from,0,0));
24     int siz=edges.size();
25     g[from].push_back(siz-2);
26     g[to].push_back(siz-1);
27 }
28 int bfs(int s,int t) //构造一次层次图
29 {
30     memset(d,-1,sizeof(d));
31     queue<int> q;
32     q.push(s);
33     d[s]=0;
34     while(!q.empty())
35     {
36         int x=q.front();q.pop();
37         for(int i=0;i<g[x].size();i++)
38         {
39             edge &e=edges[g[x][i]];
40             if(d[e.to]<0&&e.f<e.c) //d[e.to]=-1表示没访问过
41             {
42                 d[e.to]=d[x]+1;
43                 q.push(e.to);
44             }
45         }
46     }
47     return d[t];
48 }
49 int dfs(int x,int a,int t) // a表示x点能接收的量
50 {
51     if(x==t||a==0)return a;
52     int flow=0,f;//flow总的增量 f一条增广路的增量
53     for(int &i=cur[x];i<g[x].size();i++)//cur[i] &引用修改其值 从上次考虑的弧
54     {
55         edge &e=edges[g[x][i]];
56         if(d[x]+1==d[e.to]&&(f=dfs(e.to,min(a,e.c-e.f),t))>0)    //按照层次图增广 满足容量限制
57         {
58             e.f+=f;
59             edges[g[x][i]^1].f-=f;  //修改流量
60             flow+=f;
61             a-=f;
62             if(a==0) break;
63         }
64     }
65     return flow;
66 }
67 int maxflow(int s,int t)
68 {
69     int flow=0;
70     while(bfs(s,t)!=-1) //等于-1代表构造层次图失败 结束
71     {
72         memset(cur,0,sizeof(cur));
73         flow+=dfs(s,inf,t);
74     }
75     return flow;
76 }
77 int main()
78 {
79     int t,kase=1;
80     scanf("%d",&t);
81     while(t--)
82     {
83         scanf("%d%d",&n,&m);
84         init();
85         int u,v,c,f;
86         for(int i=0;i<m;i++)
87         {
88             scanf("%d%d%d",&u,&v,&c);
89             addedge(u,v,c);
90         }
91         printf("Case %d: %d\n",kase++,maxflow(1,n));
92     }
93 }

猜你喜欢

转载自www.cnblogs.com/stranger-/p/9343611.html
今日推荐