题目链接: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 }