hdu 3416 最短路+最大流
来源:互联网 发布:中国同性题材网络剧 编辑:程序博客网 时间:2024/06/05 23:42
题意: 有 n 个城市,知道了起点和终点,
有 m 条有向边,问从起点到终点不相交的最短路一共有多少条。
解法:
先dijstra(st),再dijstra(ed)一遍如果存在dist[u]+disd[v]+Edg[u].w==dis[ed] 那么将这条边加入网络中,最后求最大流即可!!
/*题意: 有 n 个城市,知道了起点和终点,有 m 条有向边,问从起点到终点不相交的最短路一共有多少条。*/#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <algorithm>#include <set>#include <map>#include <vector>#include <queue>#include <ctime>using namespace std;const int N=2002;const int M = 222222;const int INF = 1 << 30;int n,m,t,dis[N];int vis[N],head[N],Head[N],cnt;int gap[N],pre[N],cur[N];int NE,NV,sink,source,Edgeu[M],Edgev[M],Edgew[M];struct node{ int v,next,w; bool operator < (const node &a) const { return w > a.w; }} Edge[M*4],t1,t2;struct Node{ int c,pos,next;} E[M*4];void addedge(int u,int v,int w){ Edge[cnt].v = v; Edge[cnt].next = Head[u]; Edge[cnt].w = w; Head[u] = cnt++;}void addEdge(int u,int v,int c){ E[NE].c = c; E[NE].pos = v; E[NE].next = head[u]; head[u] = NE++; E[NE].c = 0; E[NE].pos = u; E[NE].next = head[v]; head[v] = NE++;}#define FF(i,NV) for(int i=0;i<NV;i++)int sap(int s,int t){ memset(dis,0,sizeof(int)*(NV+1)); memset(gap,0,sizeof(int)*(NV+1)); memset(pre,-1,sizeof(int)*(NV+1)); FF(i,NV) cur[i] = head[i]; int u = pre[s] = s,maxflow = 0,aug =INF; gap[0] = NV; while(dis[s] < NV) {loop: for(int &i = cur[u]; i != -1; i = E[i].next) { int v = E[i].pos; if(E[i].c && dis[u] == dis[v] + 1) { aug=min(aug,E[i].c); pre[v] = u; u = v; if(v == t) { maxflow += aug; for(u = pre[u]; v != s; v = u,u = pre[u]) { E[cur[u]].c -= aug; E[cur[u]^1].c += aug; } aug =INF; } goto loop; } } if( (--gap[dis[u]]) == 0) break; int mindis = INF; for(int i = head[u]; i != -1 ; i = E[i].next) { int v = E[i].pos; if(E[i].c && mindis > dis[v]) { cur[u] = i; mindis = dis[v]; } } gap[ dis[u] = mindis+1 ] ++; u = pre[u]; } return maxflow;}void dijstra(int st,int dis[]){ priority_queue<node> q; while(!q.empty()) q.top(),q.pop(); for(int i = Head[st] ; i != -1 ; i = Edge[i].next) { int v = Edge[i].v; if(Edge[i].w<dis[v]) { dis[v] = Edge[i].w; t1.w = dis[v]; t1.v = v; q.push(t1); } } dis[st]=0;//此句没加错了2次,囧~~~ vis[st] = 1; while(!q.empty()) { t1 = q.top(); q.pop(); int u = t1.v; if(vis[u]) continue; vis[u] = 1; for(int i = Head[u]; i != -1; i = Edge[i].next) { int v = Edge[i].v; if(!vis[v] && dis[v]>dis[u]+Edge[i].w) { dis[v] =dis[u]+Edge[i].w; t2.v = v; t2.w = dis[v]; q.push(t2); } } }}int main(){ int n,m,st,ed,disd[N],dist[N]; //freopen("//media/学习/ACM/input.txt","r",stdin); scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); memset(head,-1,sizeof(int)*(n+1)); memset(Head,-1,sizeof(int)*(n+1)); int i,j,u,v,w,num=0; for(NE=cnt=0,NV=n+2,j=1; j<=m; j++) { scanf("%d%d%d",&u,&v,&w); if(u!=v) { addedge(v,u,w); Edgeu[num]=u,Edgev[num]=v,Edgew[num]=w; num++; // addedge(v,u,w); } } scanf("%d%d",&st,&ed); for(cnt=i=0;i<=n+1;i++) disd[i]=dist[i] = INF; memset(vis,0,sizeof(int)*(n+1)); dijstra(ed,disd); memset(Head,-1,sizeof(int)*(n+1)); for(i=0;i<num;i++) addedge(Edgeu[i],Edgev[i],Edgew[i]); memset(vis,0,sizeof(int)*(n+1)); dijstra(st,dist); for(i=1;i<=n;i++) { for(j=Head[i];j!=-1;j=Edge[j].next) { v=Edge[j].v; if(dist[i]+disd[v]+Edge[j].w==dist[ed]) addEdge(i,v,1); } } if(dist[ed]>=INF)puts("0"); else printf("%d\n",sap(st,ed)); } return 0;}
- hdu 3416 最短路+最大流
- HDU 3416 最短路+最大流
- hdu 3416 最短路+最大流
- hdu 3416(最短路+最大流)
- 最短路+最大流 hdu 3416
- hdu 3416(最短路+最大流)
- HDU 3416 最短路+最大流
- hdu 3416(最短路+最大流)
- hdu 3416 Marriage Match IV 【网络最大流+最短路】
- HDU 3416 Marriage Match IV(最短路+最大流)
- hdu 3416 Marriage Match IV (最短路+最大流)
- HDU 3416 Marriage Match IV(最短路+最大流)
- [HDU 3416]Marriage Match IV[最大流][最短路]
- HDU-3416 Marriage Match IV(最大流+最短路)
- HDU 3416 Marriage Match IV(最短路+最大流)
- HDU-3416 Marriage Match IV(最短路+最大流)
- hdu 3599(最短路+最大流)
- hdu 3599 War(最短路+最大流)
- 日程提醒
- mod_php VS mod_fastcgi
- 黑马程序员——JAVA中易出现的小问题(二)
- oracle中 connect by prior
- SNMP(MIB(OID)& SMI & SNMP)
- hdu 3416 最短路+最大流
- 天水的骄傲-历史名将-姜维
- HDU1073:Online Judge
- hdu1081求最大子矩阵的和,DP
- VisionMobile:电信运营商创新工具箱(五)第三章:模块化的运营商
- 如何向妻子解释OOD
- 博客搬家
- SQL Server 和Oracle 数据类型对应
- 记录一下八款开源 Android 游戏引擎