HDU 3416 Marriage Match IV
2015-09-06 22:38
381 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3416
题意就是从起点到终点有几条最短路,这里有一个条件,就是每条边只能被选择一次,也就是说,1->2这条边在第一条最短路里面,那么就不能放在第二条最短路里面。首先如何判断一条边是否是最短路里面的边,那就是正向做一次最短路,反向做一次最短路,d[i]表示从起点到i点的最短距离,dr[i]表示从终点到i点的最短距离,有一点可以知道的是,d[ed]==dr[st],那么对每一条边u->v,当d[u]+dr[v]+w(u,v)==d[ed]时,这条边就是最短路中的边。这解决了第一个问题就是最短路中的边如何求的问题。接下来是第二个问题,如何求最短路的个数,这题边的次数限制,可以联想到网络流中的流量限制,就像点的限制一样,那么问题就可以解决了,利用最短路的边建一个图,边的容量为1,这样的话就可以保证每条边只经过一次,在这个图里面跑一次最大流即可。好了,所有的问题都解决了,程序就好写了。
AC代码:
题意就是从起点到终点有几条最短路,这里有一个条件,就是每条边只能被选择一次,也就是说,1->2这条边在第一条最短路里面,那么就不能放在第二条最短路里面。首先如何判断一条边是否是最短路里面的边,那就是正向做一次最短路,反向做一次最短路,d[i]表示从起点到i点的最短距离,dr[i]表示从终点到i点的最短距离,有一点可以知道的是,d[ed]==dr[st],那么对每一条边u->v,当d[u]+dr[v]+w(u,v)==d[ed]时,这条边就是最短路中的边。这解决了第一个问题就是最短路中的边如何求的问题。接下来是第二个问题,如何求最短路的个数,这题边的次数限制,可以联想到网络流中的流量限制,就像点的限制一样,那么问题就可以解决了,利用最短路的边建一个图,边的容量为1,这样的话就可以保证每条边只经过一次,在这个图里面跑一次最大流即可。好了,所有的问题都解决了,程序就好写了。
AC代码:
[code]// // Created by CQU_CST_WuErli // Copyright (c) 2015 CQU_CST_WuErli. All rights reserved. // // #include<bits/stdc++.h> #include <iostream> #include <cstring> #include <cstdio> #include <cstdlib> #include <cctype> #include <cmath> #include <string> #include <vector> #include <list> #include <map> #include <queue> #include <stack> #include <set> #include <algorithm> #include <sstream> #define CLR(x) memset(x,0,sizeof(x)) #define OFF(x) memset(x,-1,sizeof(x)) #define MEM(x,a) memset((x),(a),sizeof(x)) #define ALL(x) x.begin(),x.end() #define AT(i,v) for (auto &i:v) #define For_UVa if (kase!=1) cout << endl #define BUG cout << "I am here" << endl #define lookln(x) cout << #x << "=" << x << endl #define look(x) cout << #x << "=" << x #define SI(a) scanf("%d",&a) #define SII(a,b) scanf("%d%d",&a,&b) #define SIII(a,b,c) scanf("%d%d%d",&a,&b,&c) #define root 1,n,1 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define BigInteger bign const int MAX_L=2005;// For BigInteger const int INF_INT=0x3f3f3f3f; const long long INF_LL=0x7fffffff; const int MOD=1e9+7; const double eps=1e-9; const double pi=acos(-1); typedef long long ll; using namespace std; inline int read() { char c = getchar(); while(!isdigit(c)) c = getchar(); int x = 0; while(isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); } return x; } const int N=1100; const int M=2e5+10; // spfa; struct Edge{ int v;int w; }; vector<Edge> g ; vector<Edge> revg ; int d ,dr ; int vis ; int n,m; // Dinic; int pnt[M],head ,nxt[M],cap[M]; int cnt; int iter ,level ; //initial void init(){ for (int i=0;i<=n;i++) g[i].clear(); for (int i=0;i<=n;i++) revg[i].clear(); OFF(head);cnt=0; } // spfa void spfa(int s,int *dp,vector<Edge> *G){ CLR(vis); for (int i=1;i<=n;i++) dp[i]=INF_INT; queue<int> q; q.push(s); vis[s]=1;dp[s]=0; while (!q.empty()){ int x=q.front();q.pop(); vis[x]=0; for (int i=0;i<G[x].size();i++){ int v=G[x][i].v; int w=G[x][i].w; if (dp[v]>dp[x]+w){ dp[v]=dp[x]+w; if (!vis[v]){ vis[v]=1; q.push(v); } } } } } // Dinic void add_edge(int u,int v,int c){ pnt[cnt]=v;nxt[cnt]=head[u];head[u]=cnt; cap[cnt++]=c; } bool bfs(int s,int t){ OFF(level); queue<int> q; q.push(s); level[s]=0; while (!q.empty()){ int x=q.front();q.pop(); for (int i=head[x];~i;i=nxt[i]){ int v=pnt[i]; if (level[v]==-1 && cap[i]){ level[v]=level[x]+1; q.push(v); } } } return level[t]!=-1; } int dfs(int u,int t,int Flow){ if (u==t) return Flow; int left=Flow; for (int i=iter[u];~i;i=nxt[i]){ int v=pnt[i]; if (level[v]==level[u]+1 && cap[i]){ int d=dfs(v,t,min(left,cap[i])); cap[i]-=d; cap[i^1]+=d; left-=d; if (!left) return Flow; } } level[u]=-1; return Flow-left; } int Dinic(int s,int t){ int Max_flow=0; while (bfs(s,t)){ for (int i=1;i<=n;i++) iter[i]=head[i]; Max_flow+=dfs(s,t,INF_INT); } return Max_flow; } int main(){ #ifdef LOCAL freopen("C:\\Users\\john\\Desktop\\in.txt","r",stdin); // freopen("C:\\Users\\john\\Desktop\\out.txt","w",stdout); #endif int _;SI(_); while (_--){ SII(n,m); init(); int st,ed; for (int i=1;i<=m;i++){ int u,v,c; u=read();v=read();c=read(); if (u==v) continue; g[u].push_back(Edge{v,c}); revg[v].push_back(Edge{u,c}); } SII(st,ed); spfa(st,d,g); spfa(ed,dr,revg); // 最大流 for (int i=1;i<=n;i++){ for (int j=0;j<g[i].size();j++){ int v=g[i][j].v; int w=g[i][j].w; if (d[i]+dr[v]+w==d[ed]) { add_edge(i,v,1); add_edge(v,i,0); } } } int ans=Dinic(st,ed); cout << ans << endl; } return 0; }
相关文章推荐
- 网站的高可用架构
- 风机桨叶故障诊断(一) 样本的获取
- 阿里笔试附加题第一小题
- TCP的发送系列 — tcp_sendmsg()的实现(二)
- c++ 联合体
- JsonModel的使用
- centos7 install 安装mysql
- TCP/IP、Http、Socket的区别
- 命令行连接mysql服务器时 报Can't connect to local MySQL server through socket 'xxx.sock'错误
- yii2之登录表单
- python学习笔记---类的方法与普通方法的区别
- HTML+CSS入门
- python scrapy爬虫
- iOS 刚刚,几分钟前,几小时前,几天前,几月前,几年前
- iOS-偏好设置保存数据
- Kernel compiling for Pi 2
- 学习日志---线索二叉树和翻转二叉树
- 决策树
- 数据挖掘概述
- ajax加载报abort错误解决方法