hdu 3416 Marriage Match IV

Posted MeowMeowMeow

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 3416 Marriage Match IV相关的知识,希望对你有一定的参考价值。

链接:http://acm.hdu.edu.cn/showproblem.php?pid=3416

题意:starvae在城市A,要去城市B约妹子,要走最短路,并且每段路只能走一次,不能重复走。

题解:在走最短路的情况下,有多少条路从A到B,并且每条路是不重复的(路上经过的任何一条边都不可以重复)。首先是求最短路,然后根据所求的最短路找到这写最短路上的边,将这些边建图,求一次最大流。因为边只能走一次,所以每条边的容量是1,不用拆点(因为城市可以多次经过)。

代码:

#include <stdio.h>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <vector>
#include <queue>
#include <map>
#include <stack>
#include <iostream>
#define pi acos(-1.0)
#define INF 0x3f3f3f3f
using namespace std;
#define ll long long
const int maxn=10100;
int head[maxn],cnt=0;
struct edge
{
    int t,f,next;
}e[500010];
void init()
{
    memset(head,-1,sizeof head);
    cnt=0;
}
void add_edge(int u,int v,int f)
{
    e[cnt].t=v;e[cnt].f=f;
    e[cnt].next=head[u];head[u]=cnt++;

    e[cnt].t=u;e[cnt].f=0;
    e[cnt].next=head[v];head[v]=cnt++;
}
vector<pair<int,int> > mp[maxn];
bool vis[maxn];int dis[maxn];
void spfa(int s,int e)
{
    memset(vis,0,sizeof vis);
    memset(dis,INF,sizeof dis);
    queue<int>q;
    q.push(s),dis[s]=0,vis[s]=false;
    while(!q.empty())
    {
        int k=q.front();q.pop();
        vis[k]=0;
        for(int i=0;i<mp[k].size();i++)
        {
            int v=mp[k][i].first,w=mp[k][i].second;
            if(dis[v]>dis[k]+w)
            {
                dis[v]=dis[k]+w;
                if(!vis[v])
                    vis[v]=1,q.push(v);
            }
        }
    }
}
void getedge(int n)
{
    for(int i=1;i<=n;i++)
        for(int j=0;j<mp[i].size();j++)
        {
            int v=mp[i][j].first,w=mp[i][j].second;
            if(dis[v]==dis[i]+w)
            add_edge(i,v,1);//,printf("build %d %d %d\n",i,v,1);
        }
}
bool bfs(int s,int t)
{
    memset(dis,-1,sizeof dis);
    queue<int > q;
    dis[s]=1;q.push(s);
    while(!q.empty())
    {
        int k=q.front();q.pop();
        for(int i=head[k];i!=-1;i=e[i].next)
        {
            int v=e[i].t;
            if(e[i].f>0&&dis[v]==-1)
            {
                dis[v]=dis[k]+1;
                if(v==t) return 1;
                q.push(v);
            }
        }
    }
    return dis[t]!=-1;
}
int cur[maxn];
int dfs(int top,int t,int flow)
{
    if(top==t)
        return flow;
    int ans=0,x=0;
    for(int i=cur[top];~i;i=e[i].next)
    {
        int to=e[i].t;
        if(e[i].f>0&&dis[to]==dis[top]+1)
        {
            x=dfs(to,t,min(flow-ans,e[i].f));
            e[i].f-=x;
            e[i^1].f+=x;
            if(e[i].f)
                cur[top] = i;
            ans+=x;
            if(ans==flow)
                return flow;
        }
    }
    if(ans==0)
        dis[top]=0;
    return ans;
}
int  main()
{
    //freopen("C:\\Users\\Administrator\\Desktop\\a.txt","r",stdin);
    //ios::sync_with_stdio(false);
    //freopen("C:\\Users\\Administrator\\Desktop\\b.txt","w",stdout);
    int T,n,m;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        for(int i=0;i<=n;i++) mp[i].clear();
        init();
        for(int i=0;i<m;i++)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            mp[a].push_back(make_pair(b,c));
        }
        int s,t;
        scanf("%d%d",&s,&t);
        spfa(s,t);
        getedge(n);
        //printf("\n");
        int ans=0;
        while(bfs(s,t))
        {
            for(int i=0;i<=3*n;i++)
                cur[i]=head[i];
            ans+=dfs(s,t,INF);
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

以上是关于hdu 3416 Marriage Match IV的主要内容,如果未能解决你的问题,请参考以下文章

hdu3416 Marriage Match IV(最短路+最大流)

HDU 3416 Marriage Match IV

hdu3416Marriage Match IV (网络流+最短路)

HDU 3416 Marriage Match IV (最短路径&&最大流)

Marriage Match IV(最短路+网络流)

Marriage Match III HDU - 3277(二分权值 + 拆点 建边)