HDU 5294 Tricks Device 最短路最小割 -

来源:互联网 发布:js输出json格式 编辑:程序博客网 时间:2024/05/21 17:00

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=5294

用Dijkstra求出所有点到起点的最短路径

然后 如果dist[u]-dist[v]==w 说明该边可能是在最短路径中,但这种方法会掺入一些没用的 ,不联通的边


然后利用网络流,求出最大流就是最小割了

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<queue>#include<vector>using namespace std;const int maxn=3000+5;const int INF=0x3f3f3f3f;int N,M;//网络流struct Node{int to,flow,next;}nodes[maxn*60]; int NHead[maxn],Ntot;bool vis[maxn];void Add_Node(int u,int v,int flow){nodes[Ntot]=Node{v,flow,NHead[u]};NHead[u]=Ntot++;nodes[Ntot]=Node{u,0,NHead[v]};NHead[v]=Ntot++;}int DFS(int u,int t,int MinFlow){if(u==t) return MinFlow;vis[u]=true;for(int i=NHead[u];i!=-1;i=nodes[i].next){int flow=nodes[i].flow,v=nodes[i].to;if(!vis[v]&&flow>0){int MinF=DFS(v,t,min(MinFlow,flow));if(MinF>0){nodes[i].flow-=MinF;    //更新流量 nodes[i^1].flow+=MinF;  //添加反向边 return MinF;}}}return 0;}int Dinic(){int MaxFlow=0;for(;;){memset(vis,false,sizeof(vis));int Augment=DFS(1,N,INF);if(Augment==0) break;else MaxFlow+=Augment;}return MaxFlow;}//find the shortest pathstruct Edge{int to,weight,next;}edges[maxn*60];int Head[maxn],tot;void Add_Edge(int u,int v,int w){edges[tot]=Edge{v,w,Head[u]};Head[u]=tot++;edges[tot]=Edge{u,w,Head[v]};Head[v]=tot++;}struct HeapNode{  //prority_queue 中的优先级 int u,dist;   //dist: u点到起点的最短路 ,u: 有向边的终点 HeapNode(int u,int d):u(u),dist(d){}bool operator < (const HeapNode& h) const {return dist>h.dist;}};bool done[maxn];int dist[maxn];int minB[maxn];void Dijkstra(int s){priority_queue<HeapNode> Q;memset(dist,INF,sizeof(dist));memset(minB,INF,sizeof(minB));memset(done,false,sizeof(done));dist[s]=0;minB[s]=0; Q.push(HeapNode(s,0));while(!Q.empty()){int u=Q.top().u; Q.pop();if(done[u]) continue;done[u]=true;for(int i=Head[u];i!=-1;i=edges[i].next){Edge& e=edges[i];int v=e.to ,w=e.weight;if(dist[v]==dist[u]+w){minB[v]=min(minB[v],minB[u]+1); continue;}if(done[v])continue;if(dist[v]>dist[u]+w){dist[v]=dist[u]+w;minB[v]=minB[u]+1;Q.push(HeapNode(v,dist[v]));}}}}//build the shorest  pathvoid getPath(){memset(NHead,-1,sizeof(NHead)); Ntot=0;for(int u=1;u<=N;u++){for(int i=Head[u];i!=-1;i=edges[i].next){int v=edges[i].to,w=edges[i].weight;if(dist[v]-dist[u]==w)Add_Node(u,v,1);}}} int main(){int u,v,w;while(scanf("%d%d",&N,&M)!=EOF){memset(Head,-1,sizeof(Head)); tot=0;for(int i=0;i<M;i++){scanf("%d%d%d",&u,&v,&w);Add_Edge(u,v,w);}Dijkstra(1);getPath();printf("%d %d\n",Dinic(),M-minB[N]); }return 0;}


0 0