HDU 5294 Tricks Device(spfa+最大流-Dinic)
来源:互联网 发布:python index 编辑:程序博客网 时间:2024/06/06 16:43
Description
给你n个墓室,m条路径,一个人在1号墓室(起点),另一个人在n号墓室(终点),起点的那个人只有通过最短路径才能追上终点的那个人,而终点的那个人能切断任意路径。
第一问:终点那人要使起点那人不能追上的情况下可以切的最少的路径数,输出最少的路径数
第二问:起点那人能追上终点那人的情况下,终点那人能切断的最多的路径数,输出最多的路径数
Input
多组用例,每组用例第一行两个整数N和M表示点数和边数,之后M行每行三个整数a,b,c表示a点和b点之间有一条边权为c的边,以文件尾结束输入
Output
对于每组用例,输出两问的答案
Sample Input
8 9
1 2 2
2 3 2
2 4 1
3 5 3
4 5 4
5 8 1
1 6 2
6 7 5
7 8 1
Sample Output
2 6
Solution
首先两遍spfa求出第一个点到所有点的最短距离以及最后一个点到所有点的最短距离,求出所有最短路后以最短路为边,每条边容量为1建立新图,对新图求出最大流即为第一问答案,对新图spfa后得到第一个点到最后一个点的最短距离即为边数最少的最短路的边数,用总边数减去这个值即为第二问答案
Code
#include<cstdio>#include<iostream>#include<cstring>#include<queue>using namespace std;#define maxn 3333#define maxm 555555#define INF 0x3f3f3f3f int head[maxn],cur[maxn],d[maxn],st[maxm],s,e,no;struct point{ int u,v,flow,next; point(){}; point(int x,int y,int z,int w):u(x),v(y),next(z),flow(w){};}p[maxm];void add(int x,int y,int z){ p[no]=point(x,y,head[x],z); head[x]=no++; p[no]=point(y,x,head[y],0); head[y]=no++;}void init(){ memset(head,-1,sizeof(head)); no=0;}bool bfs(){ int i,x,y; queue<int>q; memset(d,-1,sizeof(d)); d[s]=0; q.push(s); while(!q.empty()) { x=q.front(); q.pop(); for(i=head[x];i!=-1;i=p[i].next) { if(p[i].flow&& d[y=p[i].v]<0) { d[y]=d[x]+1; if(y==e) return true; q.push(y); } } } return false;}int dinic(){ int i,loc,top,x=s,nowflow,maxflow=0; while(bfs()) { for(i=s;i<=e;i++) cur[i]=head[i]; top=0; while(true) { if(x==e) { nowflow=INF; for(i=0;i<top;i++) { if(nowflow>p[st[i]].flow) { nowflow=p[st[i]].flow; loc=i; } } for(i=0;i<top;i++) { p[st[i]].flow-=nowflow; p[st[i]^1].flow+=nowflow; } maxflow+=nowflow; top=loc; x=p[st[top]].u; } for(i=cur[x];i!=-1;i=p[i].next) if(p[i].flow&&d[p[i].v]==d[x]+1) break; cur[x]=i; if(i!=-1) { st[top++]=i; x=p[i].v; } else { if(!top) break; d[x]=-1; x=p[st[--top]].u; } } } return maxflow;}struct node{ int to; int w; int next;}edge[maxm];int head1[maxn],tol;int N,M;int dis1[maxn],dis2[maxn];int a[66666][3],b[66666][2];void init1()//初始化 { memset(head1,-1,sizeof(head1)); tol=0;}void add1(int u,int v,int c)//建边{ edge[tol].w=c; edge[tol].to=v; edge[tol].next=head1[u]; head1[u]=tol++;}void spfa(int s,int n)//单源最短路,s是起点,n是点数 { bool vis[maxn]; memset(vis,false,sizeof(vis)); queue<int>que; for(int i=0;i<=n;i++) dis1[i]=INF; dis1[s]=0; vis[s]=true; que.push(s); while(!que.empty()) { int u=que.front(); que.pop(); vis[u]=false; for(int i=head1[u];i!=-1;i=edge[i].next) { int v=edge[i].to; int w=edge[i].w; if(dis1[v]>dis1[u]+w) { dis1[v]=dis1[u]+w; if(!vis[v]) { vis[v]=true; que.push(v); } } } }}int main(){ int N,M; while(~scanf("%d%d",&N,&M)) { init1();//初始化 for(int i=0;i<M;i++) { scanf("%d%d%d",&a[i][0],&a[i][1],&a[i][2]); //建双向边 add1(a[i][0],a[i][1],a[i][2]); add1(a[i][1],a[i][0],a[i][2]); } spfa(1,N);//源点到所有点的最短距离 for(int i=1;i<=N;i++)//将dis1存储的最短距离复制到dis2中 dis2[i]=dis1[i]; spfa(N,N);//汇点到所有点的最短距离 int n=0; for(int i=0;i<M;i++)//找到所有最短路并将其存储在b数组中 { if(dis2[a[i][0]]>dis2[a[i][1]]) swap(a[i][0],a[i][1]); if(dis2[N]==dis2[a[i][0]]+a[i][2]+dis1[a[i][1]]) { b[n][0]=a[i][0]; b[n][1]=a[i][1]; n++; } } init();//初始化 s=1;//源点为1 e=N;//汇点为N for(int i=0;i<n;i++)//对所有最短路的起点和终点建容量为1的边 add(b[i][0],b[i][1],1); int ans1=dinic();//第一问答案即为新图的最大流 init1();//初始化 for(int i=0;i<n;i++) { //建双向边,边权均为1 add1(b[i][0],b[i][1],1); add1(b[i][1],b[i][0],1); } spfa(1,N);//求点1到所有点的最短距离 int ans2=M-dis1[N];//总边数减去新图起点终点最短距离即为第二问答案 printf("%d %d\n",ans1,ans2); } return 0;}
0 0
- HDU 5294 Tricks Device(spfa+最大流-Dinic)
- hdu 5294 Tricks Device spfa+网络流
- hdu 5294 Tricks Device(最短路+最大流)
- hdu 5294 Tricks Device(最短路 + 最大流)
- 【HDU 5294】Tricks Device(最短路+最大流)
- HDU 5294 Tricks Device(最短路+最大流)
- Tricks Device (hdu 5294 最短路+最大流)
- hdu 5294 Tricks Device 最短路+最大流
- 多校 hdu 5294 Tricks Device 最短路+最大流
- HDU 5294 Tricks Device (最大流+最短路)
- hdu 5294 Tricks Device (最短路+最大流)
- HDU 5294Tricks Device(最短路+最大流)
- HDU 5294 Tricks Device(最短路+最大流)
- HDU 5889 Barricade(最短路spfa+最大流dinic)
- hdu 5294 Tricks Device (最小割+最短路径+Dinic模板)
- HDU5294 Tricks Device(最大流+SPFA) 2015 Multi-University Training Contest 1
- HDU 5294(Tricks Device-最短路最小割)[Template:SPFA]
- HDU 5294 Tricks Device(多校2015 最大流+最短路啊)
- 通过SQLServer的数据库邮件来发送邮件
- 活在当下
- python爬虫 scrapy框架 知乎zhihu 模拟登陆
- HDU 2717 Catch That Cow
- 字符串排序问题
- HDU 5294 Tricks Device(spfa+最大流-Dinic)
- javascript学习笔记(一)-廖雪峰教程
- 【Android 工具类】常用工具类(方法)大全
- 《机器学习实战》(三)决策树(decision trees)
- java书籍
- 寻优方法总结:最速下降法,牛顿下降法,阻尼牛顿法,拟牛顿法DFP/BFGS
- python标准日志模块logging的使用方法
- Hbase0.98.6-CDH5.3集群搭建
- 快速排序 QuickSort