HDU 3416 Marriage Match IV
2013-10-27 20:10
316 查看
题意:给出一张n个点m条边的无向图( 2<=n<=1000, 0<=m<=100000 )和起点S、终点T。现在要求你每次从S出发都使用一条最短路到达T,并且每条路只能走一次。问最多可以从S走到T走几次最短路。
先处理出S到所有点的最短路,假设S到点i的最短路为d[i]。枚举每条边(from,to,cost),如果d[to]=d[from]+cost,在新图中加一条边(from,to,1),完了之后从S到T跑最大流。
代码:
View Code
先处理出S到所有点的最短路,假设S到点i的最短路为d[i]。枚举每条边(from,to,cost),如果d[to]=d[from]+cost,在新图中加一条边(from,to,1),完了之后从S到T跑最大流。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> #define INF 1<<30 #define maxn 1010 #define maxm 300000 using namespace std; typedef pair<int,int> pii; int v[maxm],next[maxm],w[maxm]; int first[maxn],d[maxn],work[maxn],q[maxn]; int e,S,T,N,M; struct Edge{ int from,to,dist; }edge[100010]; void init(){ e = 0; memset(first,-1,sizeof(first)); } void add_edge1(int a,int b,int c){ v[e] = b;next[e] = first[a];w[e] = c;first[a] = e++; } void add_edge2(int a,int b,int c){ //printf("add:%d to %d,cap = %d\n",a,b,c); v[e] = b;next[e] = first[a];w[e] = c;first[a] = e++; v[e] = a;next[e] = first[b];w[e] = 0;first[b] = e++; } void dijkstra(int src){ priority_queue <pii,vector<pii>,greater<pii> > q; memset(d,-1,sizeof(d)); d[src] = 0; q.push(make_pair(0,src)); while(!q.empty()){ while(!q.empty() && q.top().first > d[q.top().second]) q.pop(); if(q.empty()) break; int u = q.top().second; q.pop(); for(int i = first[u];i != -1;i = next[i]){ if(d[v[i]] > d[u] + w[i] || d[v[i]] == -1){ d[v[i]] = d[u] + w[i]; q.push(make_pair(d[v[i]],v[i])); } } } } int bfs(){ int rear = 0; memset(d,-1,sizeof(d)); d[S] = 0;q[rear++] = S; for(int i = 0;i < rear;i++){ for(int j = first[q[i]];j != -1;j = next[j]) if(w[j] && d[v[j]] == -1){ d[v[j]] = d[q[i]] + 1; q[rear++] = v[j]; if(v[j] == T) return 1; } } return 0; } int dfs(int cur,int a){ if(cur == T) return a; for(int &i = work[cur];i != -1;i = next[i]){ if(w[i] && d[v[i]] == d[cur] + 1) if(int t = dfs(v[i],min(a,w[i]))){ w[i] -= t;w[i^1] += t; return t; } } return 0; } int dinic(){ int ans = 0; while(bfs()){ memcpy(work,first,sizeof(first)); while(int t = dfs(S,INF)) ans += t; } return ans; } int main() { int kase; scanf("%d",&kase); while(kase--){ init(); scanf("%d%d",&N,&M); for(int i = 0;i < M;i++){ int a,b,c; scanf("%d%d%d",&a,&b,&c); add_edge1(a,b,c); edge[i].from = a; edge[i].to = b; edge[i].dist = c; } scanf("%d%d",&S,&T); dijkstra(S); //for(int i = 1;i <= N;i++) // printf("d[%d] = %d\n",i,d[i]); init(); for(int i = 0;i < M;i++){ int from = edge[i].from; int to = edge[i].to; int dist = edge[i].dist; if(d[to] == d[from] + dist) add_edge2(from,to,1); } int ans = dinic(); printf("%d\n",ans); } return 0; }
View Code
相关文章推荐
- HDU 3416 Marriage Match IV
- hdu 3416 Marriage Match IV
- Marriage Match IV HDU - 3416
- HDU 3416 Marriage Match IV
- Marriage Match IV (hdu 3416 网络流+spfa最短路)
- HDU 3416 Marriage Match IV
- Marriage Match IV HDU - 3416
- hdu 3416 Marriage Match IV
- HDU 3416 Marriage Match IV
- Marriage Match IV HDU - 3416
- HDU 3416 Marriage Match IV
- HDU 3416 Marriage Match IV(中等,好题) [最大流]最短路+最大流
- hdu 3416 Marriage Match IV dijkstra + isap
- 【HDOJ】3416 Marriage Match IV
- 3416 Marriage Match IV
- SPFA+Dinic HDOJ 3416 Marriage Match IV
- hdu 3081 Marriage Match II
- hdu 3416 Marriage Match IV 最大流 最短路径
- HDU 3081 Marriage Match II
- HDU 3277 Marriage Match III