hdu_5889_Barricade(最小割+最短路)

题目链接:hdu_5889_Barricade

题意:

有n个点,m条边,每个边的长度都为1,每个边有一个消耗w,如果要阻断这条路,那么就会消耗w,现在让你阻断点1到点n的所有最短路,问你最小的消耗是多少

题解:

先用dij算出最短路,然后再枚举每一条边,如果dis[u]+1=dis[v],那么久在网络流里加一条u到v的边,消耗为w,

最后用板子跑一下最大流就行了

 1 #include<bits/stdc++.h>
 2 #define F(i,a,b) for(int i=a;i<=b;++i)
 3 using namespace std;
 4 
 5 #define MAXN 20010//边数
 6 #define inf 10000000
 7 int t,n,m,x,y,c,egg[MAXN][3];
 8 int v[MAXN], w[MAXN], nxt[MAXN], gg[MAXN], ed, dd[MAXN];//n为点数,d为起点到每点的最短路程,初始化ed为0,g初始化为0
 9 void adg(int x, int y, int z) { v[++ed] = y; w[ed] = z; nxt[ed] = gg[x]; gg[x] = ed;}
10 typedef pair<int, int>P;
11 priority_queue<P, vector<P>, greater<P> > Q;
12 void dijkstra(int S) {
13     int i, x;
14     for (i = 1; i <= n; i++)dd[i] = inf; Q.push(P(dd[S] = 0, S));
15     while (!Q.empty()) {
16         P t = Q.top(); Q.pop();
17         if (dd[x = t.second] < t.first)continue;
18         for (i = gg[x]; i; i = nxt[i])if (dd[x] + w[i] < dd[v[i]])Q.push(P(dd[v[i]] = dd[x] + w[i], v[i]));
19     }
20 }
21 
22 const int N=2000,M=20010;
23 struct edge{int t,f;edge*nxt,*pair;}*g[N],*d[N],pool[M],*cur=pool;
24 struct ISAP{
25     int n,m,i,S,T,h[N],gap[N],maxflow;
26     void init(int ss,int tt){for(S=ss,T=tt,cur=pool,i=1;i<=T;i++)g[i]=d[i]=NULL,h[i]=gap[i]=0;}
27     void add(int s,int t,int f){
28         edge*p=cur++;p->t=t,p->f=f,p->nxt=g[s],g[s]=p;
29         p=cur++,p->t=s,p->f=0,p->nxt=g[t],g[t]=p;
30         g[s]->pair=g[t],g[t]->pair=g[s];
31     }
32     int sap(int v,int flow){
33         if(v==T)return flow;
34         int rec=0;
35         for(edge*p=d[v];p;p=p->nxt)if(h[v]==h[p->t]+1&&p->f){
36         int ret=sap(p->t,min(flow-rec,p->f));
37         p->f-=ret;p->pair->f+=ret;d[v]=p;
38         if((rec+=ret)==flow)return flow;
39         }
40         if(!(--gap[h[v]]))h[S]=T;
41         gap[++h[v]]++;d[v]=g[v];
42         return rec;
43     }
44     int get_ans(){
45         for(gap[maxflow=0]=T,i=1;i<=T;i++)d[i]=g[i];
46         while(h[S]<T)maxflow+=sap(S,inf);
47         return maxflow;
48     }
49 }G;
50 
51 int main(){
52     scanf("%d",&t);
53     while(t--){
54         scanf("%d%d",&n,&m);
55         G.init(1,n);
56         memset(gg,0,sizeof(gg)),ed=0;
57         F(i,1,m)
58         {
59             scanf("%d%d%d",&x,&y,&c),adg(x,y,1),adg(y,x,1);
60             egg[i][0]=x,egg[i][1]=y,egg[i][2]=c;
61         }
62         dijkstra(1);
63         F(i,1,m)
64         {
65             if(dd[egg[i][0]]+1==dd[egg[i][1]])G.add(egg[i][0],egg[i][1],egg[i][2]);
66             if(dd[egg[i][1]]+1==dd[egg[i][0]])G.add(egg[i][1],egg[i][0],egg[i][2]);
67         }
68         printf("%d
",G.get_ans());
69     }
70 }
View Code
原文地址:https://www.cnblogs.com/bin-gege/p/5889376.html