BZOJ-3931 [CQOI2015]网络吞吐量 最短路 最大流

题面

题意:所有的流量都只能最短路径上的边,每个点有个最大的吞吐量,求1号点到n号点的最大吞吐量

题解:嗯嗯嗯 题意就是题解啊 

        先求最短路,然后可以是最短路上的边连容量inf的边

        每个点都拆点,然后除了1和n两个点,都,边就是他的吞吐量,1和n边当然是inf

        唯一注意就是long long

 

  1 #include<bits/stdc++.h>
  2 #define pa pair<int,int>
  3 #define lld long long 
  4 using namespace std;
  5 #define N 1005
  6 #define M 260000
  7 #define inf 100000000000000LL
  8 namespace Dinic
  9 {
 10     int head[N],head2[N],p=1;
 11     struct Rec
 12     {
 13         int go,nex;
 14         lld c;
 15     }eg[M*2],e[M*2];
 16     void build(int a,int b,lld c)
 17     {
 18         eg[++p]=(Rec){b,head[a],-c};
 19         head[a]=p;
 20         eg[++p]=(Rec){a,head[b],0};
 21         head[b]=p;
 22     }
 23     lld dis[N],ans;
 24     int Q[N],s[N],S,T,stop;
 25     bool bfs()
 26     {
 27         memset(dis,0,sizeof(dis));
 28         dis[T]=1;
 29         Q[1]=T;
 30         for (int p1=1,p2=1;p1<=p2;p1++)
 31         {
 32             for (int i=head[Q[p1]];i;i=eg[i].nex)
 33                 if (eg[i^1].c<0&&!dis[eg[i].go])
 34                 {
 35                     dis[eg[i].go]=dis[Q[p1]]+1;
 36                     Q[++p2]=eg[i].go;
 37                 }
 38         }
 39         if (!dis[S]) return false;
 40         memcpy(head2,head,sizeof(head));
 41         return true;
 42     }
 43     bool dinic(int p,int top)
 44     {
 45         if (p==T)
 46         {
 47             lld x=inf;
 48             for (int i=1;i<=top-1;i++) if (-eg[s[i]].c<x) x=-eg[s[i]].c,stop=i;
 49             for (int i=1;i<=top-1;i++) eg[s[i]].c+=x,eg[s[i]^1].c-=x;
 50             ans+=x;
 51             return true;
 52         }
 53         for (int &i=head2[p];i;i=eg[i].nex)
 54         {
 55             if (eg[i].c<0&&dis[eg[i].go]==dis[p]-1)
 56             {
 57                 s[top]=i;
 58                 if (dinic(eg[i].go,top+1)&&top!=stop) return true;
 59             }
 60         }
 61         return false;
 62     }
 63     lld ask()
 64     {
 65         ans=0;
 66         while (bfs()) dinic(S,1);
 67         return ans; 
 68     }
 69     void init(int _S,int _T){
 70         S=_S,T=_T;
 71     }
 72 }
 73 using namespace Dinic;
 74 void clear()
 75 {
 76     p=1;
 77     memset(head,0,sizeof(head));
 78 }
 79 int n,m,ss,tt,x[M],y[M];
 80 long long xx,diss[N],z[M];
 81 void addedge(int a,int b,lld c)
 82 {
 83     p++;
 84     e[p].go=b;
 85     e[p].c=c;
 86     e[p].nex=head[a];
 87     head[a]=p;
 88 }
 89 void dijkstra()
 90 {
 91     priority_queue<pa,vector<pa>,greater<pa> >q;
 92     for (int i=1;i<=n;i++) diss[i]=inf;
 93     diss[1]=0;
 94     q.push(make_pair(0,1));
 95     while (!q.empty())
 96     {
 97         int now=q.top().second;
 98         q.pop();
 99         for (int i=head[now];i;i=e[i].nex)
100             if(diss[now]+e[i].c<diss[e[i].go])
101             {
102                 diss[e[i].go]=diss[now]+e[i].c;
103                 q.push(make_pair(diss[e[i].go],e[i].go));
104             }
105     }
106 }
107 int main()
108 {
109     scanf("%d%d",&n,&m);
110     ss=1;tt=n+n;
111     init(ss,tt);
112     for (int i=1;i<=m;i++)
113     {
114         scanf("%d%d%lld",&x[i],&y[i],&z[i]);
115         addedge(x[i],y[i],z[i]);
116         addedge(y[i],x[i],z[i]);
117     }
118     dijkstra();
119     clear();
120     for (int i=1;i<=m;i++)
121     {
122         if (diss[x[i]]+z[i]==diss[y[i]]) build(x[i]+n,y[i],inf);
123         if (diss[y[i]]+z[i]==diss[x[i]]) build(y[i]+n,x[i],inf);
124     }
125     for (int i=1;i<=n;i++)
126     {
127         scanf("%lld",&xx);
128         if (i==1 || i==n) build(i,i+n,inf);else build(i,i+n,xx);
129     }
130     printf("%lld",ask());
131     return 0;
132 }

 

 

        

posted @ 2018-09-28 21:12  口香糖万岁  阅读(163)  评论(0编辑  收藏  举报