[CQOI2015]网络吞吐量(最短路+最大流)

首先看到这个题便想到了泽州学长(%%队爷)讲的最小费用最大流,便拿来他的课件学了一学。

但是在码的过程中便会发现一个问题:最小费用最大流在最短路无法走时便会再另找一条路走,

但是这个题显然硬性规定只能按照最短路走,所以正解就是跑一遍最短路,之后按pre[]建新图

跑最大流即可。

注意:这个题还考察了化点为边的思想,和蜥蜴相似

  1 #include<bits/stdc++.h>
  2 #define int long long
  3 #define AA cout<<"Alita"<<endl
  4 #define DD cout<<"Dybala"<<endl
  5 #define m(a) memset(a,0,sizeof(a))
  6 using namespace std;
  7 const int N=1050,M=2e6+10,INF=1e12;
  8 int ans,tot=1,S,T,n,m,flag[N],dis[N],f[N],head[N],to[M],ne[M],w[M],d[M];
  9 vector<int>v[N],g[N],pre[N];
 10 struct point
 11 {
 12         int x,y;
 13         friend bool operator <(point a,point b)
 14         {
 15                 return a.y>b.y;
 16         }
 17 };
 18 void add(int x,int y,int z)
 19 {
 20         to[++tot]=y;
 21         w[tot]=z;
 22         ne[tot]=head[x];
 23         head[x]=tot;
 24 }
 25 void Plus(int x,int y,int z)
 26 {
 27         v[x].push_back(y);
 28         g[x].push_back(z);
 29 }
 30 void DJ()
 31 {
 32         memset(dis,0x7f,sizeof(dis));
 33         memset(flag,0,sizeof(flag));
 34         priority_queue<point>q;
 35         point p={S,0};
 36         dis[S]=0;
 37         q.push(p);
 38         while(q.size())
 39         {
 40                 point p=q.top();
 41                 q.pop();
 42                 if(flag[p.x]) continue;
 43                 flag[p.x]=1;
 44                 for(int i=0;i<v[p.x].size();i++)
 45                 {
 46                         int y=v[p.x][i];
 47                         if(dis[y]>dis[p.x]+g[p.x][i])
 48                         {
 49                                 dis[y]=dis[p.x]+g[p.x][i];
 50                                 pre[y].clear();
 51                                 if(p.x!=n) pre[y].push_back(p.x);
 52                                 point b={y,dis[y]};
 53                                 q.push(b);
 54                         }
 55                         else if(dis[y]==dis[p.x]+g[p.x][i])
 56                         {
 57                                 if(p.x!=n) pre[y].push_back(p.x);
 58                         }
 59                 }
 60         }
 61 }
 62 bool bfs(int s)
 63 {
 64         memset(d,0,sizeof(d));
 65         queue<int>q;
 66         q.push(s);
 67         d[s]=1;
 68         while(q.size())
 69         {
 70                 int x=q.front();
 71                 q.pop();
 72                 for(int i=head[x];i;i=ne[i])
 73                 {
 74                         int y=to[i];
 75                         if(!w[i]||d[y]) continue;
 76                         d[y]=d[x]+1;
 77                         if(y==S) return true;
 78                         q.push(y);
 79                 }
 80         }
 81         return false;
 82 }
 83 int dfs(int x,int in)
 84 {
 85         if(x==S) return in;
 86         int out=0;
 87         for(int i=head[x];i;i=ne[i])
 88         {
 89                 int y=to[i];
 90                 if(!w[i]||d[y]!=d[x]+1) continue;
 91                 int tmp=dfs(y,min(in,w[i]));
 92                 in-=tmp;
 93                 out+=tmp;
 94                 w[i]-=tmp;
 95                 w[i^1]+=tmp;
 96         }
 97         if(!out) d[x]=0;
 98         return out;
 99 }
100 signed main()
101 {
102         //freopen("1.in","r",stdin);
103         scanf("%lld%lld",&n,&m);
104         S=1;T=n*2;
105         for(int i=1,x,y,z;i<=m;i++)
106         {
107                 scanf("%lld%lld%lld",&x,&y,&z);
108                 Plus(x,y,z);
109                 Plus(y,x,z);
110         }
111         for(int i=1;i<=n;i++)
112         {
113                 scanf("%lld",&f[i]);
114                 if(i==1||i==n) continue;
115                 add(i,n+i,f[i]);
116                 add(n+i,i,0);
117         }
118         DJ();
119         for(int i=1;i<=n;i++)
120         {
121                 for(int j=0;j<pre[i].size();j++)
122                 {
123                         add(n+i,pre[i][j],INF);
124                         add(pre[i][j],n+i,0);
125                 }
126         }
127         while(bfs(T)) 
128         {
129                 ans+=dfs(T,INF);
130         }
131         printf("%lld",ans);
132         return 0;
133 }
View Code

 

posted @ 2019-08-08 18:08  ATHOSD  阅读(101)  评论(0编辑  收藏  举报