您的位置:首页 > 其它

HDU 3416 Marriage Match IV (求最短路的条数,最大流)

2016-08-09 10:42 537 查看

Marriage Match IV

题目链接:

http://acm.hust.edu.cn/vjudge/contest/122685#problem/Q

Description

Do not sincere non-interference。

Like that show, now starvae also take part in a show, but it take place between city A and B. Starvae is in city A and girls are in city B. Every time starvae can get to city B and make a data with a girl he likes. But there are two problems with it, one is starvae must get to B within least time, it's said that he must take a shortest path. Other is no road can be taken more than once. While the city starvae passed away can been taken more than once.

So, under a good RP, starvae may have many chances to get to city B. But he don't know how many chances at most he can make a data with the girl he likes . Could you help starvae?

Input

The first line is an integer T indicating the case number.(1<=T<=65)

For each case,there are two integer n and m in the first line ( 2<=n<=1000, 0<=m<=100000 ) ,n is the number of the city and m is the number of the roads.

Then follows m line ,each line have three integers a,b,c,(1<=a,b<=n,0<c<=1000)it means there is a road from a to b and it's distance is c, while there may have no road from b to a. There may have a road from a to a,but you can ignore it. If there are two roads from a to b, they are different.

At last is a line with two integer A and B(1<=A,B<=N,A!=B), means the number of city A and city B.

There may be some blank line between each case.

Output

Output a line with a integer, means the chances starvae can get at most.

Sample Input

3
7 8
1 2 1
1 3 1
2 4 1
3 4 1
4 5 1
4 6 1
5 7 1
6 7 1
1 7

6 7
1 2 1
2 3 1
1 3 3
3 4 1
3 5 1
4 6 1
5 6 1
1 6

2 2
1 2 1
1 2 2
1 2


Sample Output

2

1

1

Hint

题意:

求最短路的条数.

要求这些路径互相没有相同的边.

题解:

由于要求同一条边不能出现在两条最短路中.

所以直接标记出最短路中的边,对这些边跑一次最大流即可. (这里直接用了sap模版)

若这个题没有不共边的要求,就直接对最短路中的边dfs即可.

HDU1142-A Walk Through the Forest

题解:http://www.cnblogs.com/Sunshine-tcf/p/5752205.html

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#define LL long long
#define eps 1e-8
#define maxn 501000
#define mod 1000000007
#define inf 0x3f3f3f3f
#define IN freopen("in.txt","r",stdin);
using namespace std;

int n, m;
typedef pair<int,int> pii;
priority_queue<pii,vector<pii>,greater<pii> > q;
bool vis[maxn];
int edges, u[maxn], v[maxn], w[maxn];
int first[maxn], _next[maxn];
int dist[maxn];
int pre1[maxn];

void add_edge(int s, int t, int val) {
u[edges] = s; v[edges] = t; w[edges] = val;
_next[edges] = first[s];
first[s] = edges++;
}

void dijkstra(int s) {
memset(pre1, -1, sizeof(pre1));
memset(vis, 0, sizeof(vis));
for(int i=1; i<=n; i++) dist[i]=inf; dist[s] = 0;
while(!q.empty()) q.pop();
q.push(make_pair(dist[s], s));

while(!q.empty()) {
pii cur = q.top(); q.pop();
int p = cur.second;
if(vis[p]) continue; vis[p] = 1;
for(int e=first[p]; e!=-1; e=_next[e]) if(dist[v[e]] > dist[p]+w[e]){
dist[v[e]] = dist[p] + w[e];
q.push(make_pair(dist[v[e]], v[e]));
pre1[v[e]] = p;
}
}
}

//最大流SAP
struct Node {
int to,_next,cap;
}edge[maxn];
int tol;
int head[maxn];
int gap[maxn],dis[maxn],pre[maxn],cur[maxn];
void init() {
tol=0;
memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int w,int rw=0) {
edge[tol].to=v;edge[tol].cap=w;edge[tol]._next=head[u];head[u]=tol++;
edge[tol].to=u;edge[tol].cap=rw;edge[tol]._next=head[v];head[v]=tol++;
}

int sap(int start,int end,int nodenum)
{
memset(dis,0,sizeof(dis));
memset(gap,0,sizeof(gap));
memcpy(cur,head,sizeof(head));
int u=pre[start]=start,maxflow=0,aug=-1;
gap[0]=nodenum;
while(dis[start]<nodenum)
{
loop:
for(int &i=cur[u];i!=-1;i=edge[i]._next)
{
int v=edge[i].to;
if(edge[i].cap&&dis[u]==dis[v]+1)
{
if(aug==-1||aug>edge[i].cap)
aug=edge[i].cap;
pre[v]=u;
u=v;
if(v==end)
{
maxflow+=aug;
for(u=pre[u];v!=start;v=u,u=pre[u])
{
edge[cur[u]].cap-=aug;
edge[cur[u]^1].cap+=aug;
}
aug=-1;
}
goto loop;
}
}
int mindis=nodenum;
for(int i=head[u];i!=-1;i=edge[i]._next)
{
int v=edge[i].to;
if(edge[i].cap&&mindis>dis[v])
{
cur[u]=i;
mindis=dis[v];
}
}
if((--gap[dis[u]])==0)break;
gap[dis[u]=mindis+1]++;
u=pre[u];
}
return maxflow;
}

int main(void)
{
//IN;

int t; cin >> t; int ca = 1;
while(t--)
{
memset(first, -1, sizeof(first)); edges = 0;
cin >> n >> m;

while(m--) {
int u,v,w; scanf("%d %d %d", &u, &v, &w);
if(u == v) continue;
add_edge(u, v, w);
}
int s, t; cin  >> s >> t;

dijkstra(s);

init();
for(int e=0; e<edges; e++) {
//判断是否是最短路上的边
if(dist[v[e]] == dist[u[e]]+w[e]) {
addedge(u[e], v[e], 1);
}
}

int paths = sap(s, t, n);

printf("%d\n", paths);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: