hdu 5294 Tricks Device spfa+网络流
来源:互联网 发布:java list集合排序 编辑:程序博客网 时间:2024/05/21 07:06
题目要求两个答案,先求第二个答案,用spfa跑两次,第一次以1为起点,记录一下到终点最短距离通过了几条边。第二次以2为起点,跑一下。第一问题为最小移去多少条边,图不连通,题目中只需要移动最短路上的边,所以根据前两次spfa的结果,将最短路上的边找出来,流量记为1构成一张新图,转化为网络流问题,汇点的流量就是答案。
#include<stdio.h>#include<algorithm>#include<string.h>#include<vector>#include<queue>using namespace std;const int inf=0x7fffffff;const int N=2048;const int M=60000+5;int n,m,f[N],dis[N][2],cnt[N];struct{ int u,v,c;} edge[M];vector<int>g[M];struct Edge{ int from,to,cap,flow;};vector<Edge>edges;vector<int>G[N];int s,t;int vis[N];int d[N];int cur[N];int spfa(int st,int id){ queue<int>q; int i,u,v,k; memset(f,0,sizeof(f)); for(i=0; i<=n; i++) cnt[i]=dis[i][id]=inf; dis[st][id]=0; cnt[st]=0; q.push(st); while(!q.empty()) { u=q.front(); q.pop(); f[u]=0; for(i=0; i<g[u].size(); i++) { k=g[u][i]; if(edge[k].u==u) v=edge[k].v; if(edge[k].v==u) v=edge[k].u; if(dis[u][id]+edge[k].c<=dis[v][id]) { if(dis[u][id]+edge[k].c==dis[v][id]) cnt[v]=min(cnt[u]+1,cnt[v]); else cnt[v]=cnt[u]+1; dis[v][id]=dis[u][id]+edge[k].c; if(f[v]==0) { f[v]=1; q.push(v); } } } }}void AddEdge(int from,int to,int cap){ Edge tp; tp.from=from,tp.to=to,tp.cap=cap,tp.flow=0; edges.push_back(tp); tp.from=to,tp.to=from,tp.cap=0,tp.flow=0; edges.push_back(tp); int g_size=edges.size(); G[from].push_back(g_size-2); G[to].push_back(g_size-1);}bool BFS(){ memset(vis,0,sizeof(vis)); queue<int>Q; Q.push(s); d[s]=0; vis[s]=1; while(!Q.empty()) { int x=Q.front(); Q.pop(); for(int i=0; i<G[x].size(); i++) { Edge &e=edges[G[x][i]]; if(!vis[e.to]&&e.cap>e.flow) { vis[e.to]=1; d[e.to]=d[x]+1; Q.push(e.to); } } } return vis[t];}int DFS(int x,int a){ if(x==t||a==0) return a; int flow=0,f; for(int &i=cur[x]; i<G[x].size(); i++) { Edge &e=edges[G[x][i]]; if(d[x]+1==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0) { e.flow+=f; edges[G[x][i]^1].flow-=f; flow+=f; a-=f; if(a==0) break; } } if(!flow) d[x] = -1; return flow;}int Maxflow(int st,int ed){ int flow=0; while(BFS()) { memset(cur,0,sizeof(cur)); flow+=DFS(st,inf); } return flow;}int main(){ int i,dist,ans,u,v,c; while(~scanf("%d%d",&n,&m)) { for(i=0; i<=n; i++) { g[i].clear(); G[i].clear(); } edges.clear(); for(i=0; i<m; i++) { scanf("%d%d%d",&u,&v,&c); edge[i].u=u; edge[i].v=v; edge[i].c=c; g[u].push_back(i); g[v].push_back(i); } spfa(1,0); ans=cnt[n]; dist=dis[n][0]; spfa(n,1); for(i=0; i<m; i++) { u=edge[i].u; v=edge[i].v; c=edge[i].c; if(dis[u][0]+dis[v][1]+c==dist||dis[v][0]+dis[u][1]+c==dist) { AddEdge(u,v,1); AddEdge(v,u,1); } } s=1;t=n; printf("%d %d\n",Maxflow(1,n),m-ans); } return 0;}
0 0
- hdu 5294 Tricks Device spfa+网络流
- HDU 5294 Tricks Device(spfa+最大流-Dinic)
- 【网络流+最短路】 HDU 5294 Tricks Device
- HDU 5294 Tricks Device (最短路+网络流)
- 最短路,网络流(HDU 5294,Tricks Device)
- HDU 5294(Tricks Device-最短路最小割)[Template:SPFA]
- hdu 5294 Tricks Device
- hdu 5294 Tricks Device
- hdu 5294 Tricks Device
- hdu 5294 Tricks Device
- HDU 5294 Tricks Device
- 网络流 - hdu5294 Tricks Device
- hdu 5294 - Tricks Device(2015 Multi-University Training Contest 1 )最短路+网络流
- hdu 5294 Tricks Device(最短路+网络流(最小割))
- HDU 5294 Tricks Device 残余网络(最短路+最大流)**
- hdu 5294 Tricks Device(15多校第一场1007)(spfa+最小割)
- Tricks Device (hdu 5294 最短路+最大流)
- hdu 5294 Tricks Device(最短路+最大流)
- Android之PinnedHeaderExpandableListView- 仿ios的UITableView的header置顶效果
- 普通排序--插入排序
- JavaScript学习(5.1):表达式语句、符合语句和空语句
- jQuery-easyui中的combobox如何动态获取下拉框内容
- Codeforces Round #333(div1.b/div2.d) / problem 601b - 单调栈
- hdu 5294 Tricks Device spfa+网络流
- 线性表的顺序存储
- Zstack中使用串口
- js将form内的表单序列化为json字符串、数组、对象
- LeetCode 100 Same Tree
- Python机器学习——sklearn常用模块及类及方法
- 线性表的链式存储
- Servlet :防止表单重复提交
- jQuery Validate验证框架详解