hdu 5294 Tricks Device(15多校第一场1007)(spfa+最小割)
来源:互联网 发布:通讯录医生是什么软件 编辑:程序博客网 时间:2024/06/04 19:16
//最小割+spfa#include<cstdio>#include<cstring>#include<queue>using namespace std;typedef long long LL;#define MIN(a,b) a<b?a:b#define MAX(a,b) a>b?a:bconst int N=50000,M=500000,INF=0x3fffffff;int n,m;struct EDGE{ int from,to,cap,next;}edge[M],edge2[M];int head[N];int cnt;void addedge(int u,int v,int w){ edge[cnt].from=u;edge[cnt].to=v;edge[cnt].cap=w;edge[cnt].next=head[u]; head[u]=cnt++;}void addedge2(int u,int v,int w){ edge2[cnt].from=u;edge2[cnt].to=v;edge2[cnt].cap=w;edge2[cnt].next=head[u]; head[u]=cnt++;}int dist[N][2];int step[N];int vis[N];void SPFA(int st,int num){ for(int i=0;i<=n;i++)dist[i][num]=INF,step[i]=INF; memset(vis,0,sizeof(vis)); queue<int>q; q.push(st); dist[st][num]=0; step[st]=0;vis[st]=1; while(!q.empty()){ int k=q.front(); q.pop();vis[k]=0; for(int i=head[k];i!=-1;i=edge[i].next){ int v=edge[i].to; if(dist[k][num]+edge[i].cap<dist[v][num]){ dist[v][num]=dist[k][num]+edge[i].cap; step[v]=step[k]+1; if(!vis[v]){ q.push(v); vis[v]=1; } } else if(dist[k][num]+edge[i].cap==dist[v][num]){ step[v]=MIN(step[v],step[k]+1); } } }}int q[N];int dep[N];//dep为距离编号int gap[N];//gap[x]=y:说明残留网络中dep[i]==x的节点有y个struct SAP{ int sum; int src,des; void init(){ src = 1; des = n; } void bfs(int start,int end){ memset(dep, -1, sizeof(dep)); memset(gap, 0, sizeof(gap)); memset(q,-1,sizeof(q)); gap[0]=1; int front,rear; front=rear=0; dep[end]=0; q[rear++]=end; while(front!=rear){ int u=q[front++]; if(front==N)front=0; for(int i=head[u];i!=-1;i=edge2[i].next){ int v=edge2[i].to; if(dep[v]!=-1)continue; q[rear++]=v; if(rear==N)rear=0; dep[v]=dep[u]+1; ++gap[dep[v]]; } } } int Maxflow(){ int res=0; bfs(src,des); int cur[N],stack[N]; int top=0; memcpy(cur,head,sizeof(head)); int u=src; int i; while(dep[src]<n){//如果src找不到一个可达点,则dep[src] = n + 1自动退出 if(u==des){//找到汇点 int temp=INF,inser=n; for(int i=0;i<top;i++){//找从src点到des点的所有边中的最容量为temp,而那条边的编号为insert if(temp>edge2[stack[i]].cap){ temp=edge2[stack[i]].cap; inser=i; } } for(int i=0;i<top;i++){//将正向边-temp,反向变+temp edge2[stack[i]].cap-=temp; edge2[stack[i]^1].cap+=temp; } res+=temp;//总的流量加temp top=inser;//stack只保留从src到最小边insert“前向点”之间的边的信息,即insert边以后的边信息都不要 u=edge2[stack[top]].from;////u为insert的”前向点“ } for(i=cur[u];i!=-1;i=edge2[i].next){////当没有断层,找出一个可达边 if(edge2[i].cap!=0&&dep[u]==dep[edge2[i].to]+1)break; } if(i!=-1)//找到这个可达边,只能走到dep[u]-1; { cur[u]=i;//优化下次找dep[u] - 1不用从头开始找了 stack[top++]=i; u=edge2[i].to; } else{//当没有找到深度为dep[u] - 1的可达边,那只能找深度更大的边 if(--gap[dep[u]]==0)break; //出现断层,无增广路; int minn = n; //从头开始找出深度最小的可达边 for(i=head[u];i!=-1;i=edge2[i].next){ if(edge2[i].cap==0)continue; if(minn>dep[edge2[i].to]){ minn=dep[edge2[i].to]; cur[u]=i; } } dep[u]=minn+1;//更新深度 ++gap[dep[u]]; if(u!=src)//如果u不是源点,还得回溯到dep[u] + 1(这里的dep[u]!=minn + 1)层,并将dep[u]层点全部修改变大。一直回溯到源点 u=edge2[stack[--top]].from; } } return res; }};SAP sap;int main(){ while(scanf("%d%d",&n,&m)!=EOF){ cnt=0; memset(head,-1,sizeof(head)); for(int i=0;i<m;i++){ int u,v,w; scanf("%d%d%d",&u,&v,&w); addedge(u,v,w); addedge(v,u,w); } SPFA(1,0); int ans=step[n]; SPFA(n,1); int len=dist[n][0]; cnt=0; memset(head,-1,sizeof(head)); for(int i=0;i<2*m;i+=2){//重新建图 int u=edge[i].from,v=edge[i].to; if(dist[u][0]+edge[i].cap+dist[v][1]==len){ addedge2(u,v,1); addedge2(v,u,0); } else if(dist[u][1]+edge[i].cap+dist[v][0]==len){ addedge2(v,u,1); addedge2(u,v,0); } } sap.init(); printf("%d %d\n",sap.Maxflow(),m-ans); } return 0;}
0 0
- hdu 5294 Tricks Device(15多校第一场1007)(spfa+最小割)
- HDU 5294 Tricks Device(2015多校第一场 最短路 + 最小割)
- HDU 5294(Tricks Device-最短路最小割)[Template:SPFA]
- hdu5294 Tricks Device 最短路+最小割 多校联合第一场
- 【hdoj 5294】 Tricks Device 【最小割+最短路spfa】
- HDU 5294 Tricks Device (最短路上的最小割) 2015多校训练1007
- hdu HDU 5294 - Tricks Device(最短路+最小割)
- HDU 5294 Tricks Device (最短路变体) 2015多校联合第一场
- HDU 5294 - Tricks Device(最短路+最小割)
- hdu 5294 Tricks Device 最短路建图+最小割
- HDU 5294 Tricks Device(最短路+最小割)
- HDU 5294 Tricks Device 最短路+最小割
- HDU 5294 Tricks Device(最短路最小割)
- HDU 5294 Tricks Device 最短路最小割 -
- hdu 5294 Tricks Device(2015多校第一场第7题)最大流+最短路
- hdu 5294 Tricks Device spfa+网络流
- HDU 5294--Tricks Device【最小割 && 最短路处理,新建图】
- hdu 5294 Tricks Device(最短路+网络流(最小割))
- hdoj-2072-单词数(结构体、大坑)
- 猫猫学iOS之小知识之_xcode插件的删除方法_自动提示图片插件KSImageNamed有时不灵_分类或宏之类不能自动提示,
- HDU5294.Tricks Device(多校第七题)
- 离别
- 奖学金文章连载1北京51班 任伟伟
- hdu 5294 Tricks Device(15多校第一场1007)(spfa+最小割)
- 杭电1425sort
- 【翻译】如何创建Ext JS暗黑主题之二
- Set Matrix Zeroes
- 史上最全 前端开发面试问题及答案整理 http://segmentfault.com/blog/trigkit4/1190000002562454
- GCD 深入理解(二)
- hdu 5296 Annoying problem(15多校第一场1009)(在线lca+dfs序)
- Reproducible Research in Computational Science
- HTTP协议讲解