标签:
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
/* * HDU 5889 Barricade * 求堵住从1到n的最短路的最小花费 * * bfs + 最小割 * 首先用Dij或者bfs求出dis数组,接着从终点出发,倒着bfs找出所有最短路径重新建图 * 然后就是一个裸的最小割了,就等于最大流 */ #include <stdio.h> #include <string.h> #include <iostream> #include <queue> #include <map> #include <vector> using namespace std; struct NetFlow { const static int MAXN = 5000+10; const static int MAXE = 500000; const static long long INF = 1e18; struct Edge { int from,to,next,cap,flow; Edge(){} Edge(int u,int v,int c,int f,int nxt):from(u),to(v),cap(c),flow(f),next(nxt) {} }edge[MAXE]; int head[MAXN],tol,N; int cur[MAXN],pre[MAXN],dis[MAXN],gap[MAXN]; void init(int _n) { N=_n,tol=0; memset(head,-1,sizeof(head)); } void link(int u,int v,int cap)//s->t,cap { edge[tol]=Edge(u,v,cap,0,head[u]);head[u]=tol++; edge[tol]=Edge(v,u,0,0,head[v]);head[v]=tol++; } long long ISAP(int S,int T) {//S -> T long long maxflow=0,aug=INF; int flag=false,u,v; for (int i=0;i<N;++i) cur[i]=head[i],gap[i]=dis[i]=0; for (gap[S]=N,u=pre[S]=S;dis[S]<N;flag=false) { for (int &it=cur[u];it!=-1;it=edge[it].next) { if (edge[it].cap>edge[it].flow&&dis[u]==dis[v=edge[it].to]+1) { aug=min(aug,(long long)(edge[it].cap-edge[it].flow)); pre[v]=u,u=v; flag=true; if (u==T) { for(maxflow+=aug;u!=S;) { edge[cur[u=pre[u]]].flow+=aug; edge[cur[u]^1].flow-=aug; } aug=INF; } break; } } if(flag) continue; int mx=N; for(int it=head[u];it!=-1;it=edge[it].next) { if(edge[it].cap>edge[it].flow&&dis[edge[it].to]<mx) { mx=dis[edge[it].to]; cur[u]=it; } } if((--gap[dis[u]])==0) break; ++gap[dis[u]=mx+1]; u=pre[u]; } return maxflow; } }NF; const int MAXN = 5000+10; const int MAXE = 200000; const int INF = 1e9; struct node{ int v,c; node(int _v=0,int _c=0):v(_v),c(_c){} bool operator <(const node &rhs) const{ return c>rhs.c; } }; struct Ed { int u,v,w; }e; vector<Ed>p; struct Edge{ int to,cost; int w; int next; }; Edge edge[MAXE]; int head[MAXN],tot; bool vis[MAXN]; int dis[MAXN]; void Dijkstra(int n,int start) { memset(vis,false,sizeof(vis)); for(int i=1;i<=n;i++) dis[i]=INF; priority_queue<node>q; while(!q.empty()) q.pop(); dis[start]=0; q.push(node(start,0)); node next; while(!q.empty()){ next=q.top(); q.pop(); int u=next.v; if(vis[u]) continue; vis[u]=true; for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].to; int cost=edge[i].cost; if(!vis[v]&&dis[v]>dis[u]+cost){ dis[v]=dis[u]+cost; q.push(node(v,dis[v])); } } } } void init() { tot=0; memset(head,-1,sizeof(head)); } void addedge(int u,int v,int w,int ww) { edge[tot].to=v; edge[tot].cost=w; edge[tot].w=ww; edge[tot].next=head[u]; head[u]=tot++; } void bfs(int T) { memset(vis,0,sizeof(vis)); queue<int>Q; Q.push(T); vis[T]=true; while(!Q.empty()) { int u=Q.front(); Q.pop(); for(int i=head[u];i!=-1;i=edge[i].next) { int ds=edge[i].cost; int v=edge[i].to; if(ds+dis[v]==dis[u]) { e.u=v,e.v=u,e.w=edge[i].w; p.push_back(e); if(!vis[v]) { vis[v]=1; Q.push(v); } } } } } int main() { int T; int n,m,u,v,w; //freopen("in.txt","r",stdin); scanf("%d",&T); while(T--) { init(); p.clear(); scanf("%d%d",&n,&m); while(m--) { scanf("%d%d%d",&u,&v,&w); addedge(u,v,1,w); addedge(v,u,1,w); } Dijkstra(n,1); bfs(n); int sz=p.size(); NF.init(n+1); for(int i=0;i<sz;i++) { u=p[i].u; v=p[i].v; w=p[i].w; NF.link(u,v,w); } long long ans=NF.ISAP(1,n); printf("%lld\n",ans); } return 0; }
HDU 5889 Barricade (bfs + 最小割)
标签:
原文地址:http://www.cnblogs.com/wangdongkai/p/5880112.html