zoukankan      html  css  js  c++  java
  • HDU 3416 Marriage Match IV (求最短路的条数,最大流)

    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

    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

    </big>
    
    
    ##Sample Output
    <big>
    2
    1
    1
    </big>
    
    ##Hint
    <big>
    </big>
    
    
    
    
    
    <br/>
    ##题意:
    <big>
    求最短路的条数.
    要求这些路径互相没有相同的边.
    </big>
    
    
    <br/>
    ##题解:
    <big>
    由于要求同一条边不能出现在两条最短路中.
    所以直接标记出最短路中的边,对这些边跑一次最大流即可. (这里直接用了sap模版)
    <br/>
    若这个题没有不共边的要求,就直接对最短路中的边dfs即可.
    [HDU1142-A Walk Through the Forest](http://acm.hdu.edu.cn/showproblem.php?pid=1142)
    题解:http://www.cnblogs.com/Sunshine-tcf/p/5752205.html
    </big>
    
    
    
    
    <br/>
    ##代码:
    ``` cpp
    #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
    ", paths);
        }
    
        return 0;
    }
    
  • 相关阅读:
    OEA框架学习:缓存
    2012年 博文整理
    技术支持经验总结
    OEA框架学习:元数据设计
    安装后新建Android出现“AndroidManifest.xml 系统找不到指定的文件”解决方案
    Android控件学习笔记之 GridView(实现九宫格)
    获取url地址中主机的域名
    C# 语音读取字符串
    JSON省市联动
    MOTO Droid手机自定义本地铃声设置方法
  • 原文地址:https://www.cnblogs.com/Sunshine-tcf/p/5752180.html
Copyright © 2011-2022 走看看