zoukankan      html  css  js  c++  java
  • hdu3416 Marriage Match IV 最短路+最大流

    Marriage Match IV

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 5521    Accepted Submission(s): 1621


    Problem 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
     题目大意: 求有多少条没有公共边的最短路
     题解:先跑一边单源最短路,然后遍历所有的边,对于edge[i],如果dis[edge[i].from] + edge[i].w = dis[edge[i].to],说明该边在在最短路中,在新图中加入该边。
       然后跑一遍每条边cap均为1的最大流即可。一开始跑的spfa+dinic,疯狂TLE,调试半天后改成spfa+isap一发AC....
       不是很懂是这道题卡dinic还是我写臭了....
     
    /*
    AC代码
    spfa+isap
    */
    #include <bits/stdc++.h>
    using namespace std;
    
    int T,n,m;
    int s,t;
    
    const int MAXN = 100010;
    const int MAXM = 400010;
    const int INF = 0x3f3f3f3f;
    struct Edge
    {
        int to,next,cap,flow;
    } edge[MAXM]; 
    int tol;
    int head[MAXN];
    int gap[MAXN],dep[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].flow = 0;
                     edge[tol].next = head[u]; head[u] = tol++;
                 edge[tol].to = u; edge[tol].cap = rw;edge[tol].flow = 0;
                     edge[tol].next = head[v]; head[v] = tol++;
    }
    int Q[MAXN];
    void BFS(int start,int end)
    {
        memset(dep, -1,sizeof(dep));
        memset(gap,0,sizeof(gap));
        gap[0] = 1;
        int front = 0, rear = 0;
        dep[end] = 0;
        Q[rear++] = end;
        while(front != rear)
        {
            int u = Q[front++];
            for(int i = head[u]; i != -1;i = edge[i].next){
                    int v = edge[i].to;
                    if(dep[v] != -1)continue;
                        Q[rear++] = v;
                        dep[v] = dep[u] + 1;
                        gap[dep[v]]++;
            }
    }
    }
    int S[MAXN];
    int sap(int start,int end,int N)
    {
        BFS(start,end);
        memcpy(cur,head,sizeof(head));
        int top = 0;
        int u = start;
        int ans = 0;
        while(dep[start] < N)
        {
            if(u == end)
            {
                int Min = INF;
                int inser;
                for(int i = 0; i < top; i++)
                    if(Min > edge[S[i]].cap -edge[S[i]].flow)
                    {
                        Min = edge[S[i]].cap -edge[S[i]].flow;
                        inser = i;
                    }
                for(int i = 0; i < top; i++)
                {
                    edge[S[i]].flow += Min;
                    edge[S[i]^1].flow -= Min;
                }
                ans += Min;
                top = inser;
                u = edge[S[top]^1].to;
                continue;
    
            }
            bool flag = false;
            int v;
            for(int i = cur[u]; i != -1; i = edge[i].next)
            {
                v = edge[i].to;
                if(edge[i].cap -edge[i].flow && dep[v]+1 == dep[u])
                {
                    flag = true;
                    cur[u] = i;
                    break;
                }
            }
            if(flag)
            {
                S[top++] = cur[u];
                u = v;
                continue;
            }
            int Min = N;
            for(int i = head[u]; i != -1; i = edge[i].next)
                if(edge[i].cap -edge[i].flow && dep[edge[i].to] < Min)
                {
                    Min = dep[edge[i].to];
                    cur[u] = i;
                }
            gap[dep[u]]--;
            if(!gap[dep[u]])
                return ans;
            dep[u] = Min + 1;
            gap[dep[u]]++;
            if(u != start)
                u = edge[S[--top]^1].to;
        }
        return ans;
    }
    
    struct K
    {
        int from,next,to,w;
    } e[MAXM];
    int dis[MAXN],vis[MAXN];
    
    queue <int> q;
    int c[MAXN];
    void spfa(int s,int t,int n)
    {
        memset(dis,INF,sizeof(dis));
        memset(vis,0,sizeof(vis));
        memset(c,0,sizeof(c));
        vis[s] = true;
        dis[s] = 0;
        while(!q.empty())
            q.pop();
        q.push(s);
        c[s] = 1;
        while(!q.empty())
        {
            int u = q.front();
            q.pop();
            vis[u] = false;
            for (int i = head[u]; i != -1; i = e[i].next)
            {
                int v = e[i].to,w = e[i].w;
                if (dis[v] > dis[u] + w)
                {
                    dis[v] = dis[u] + w;
                    if (!vis[v])
                    {
                        vis[v] = 1;
                        if (++c[v] > n)
                            return;
                        q.push(v);
                    }
                }
            }
        }
    }
    
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&m);
            int tt = 0;
            memset(head,-1,sizeof(head));
            for (int i = 0; i < m; ++i)
            {
                int u,v,w;
                scanf("%d%d%d",&u,&v,&w);
                if (u == v)
                    continue;
                e[tt] = K{u,head[u],v,w};
                head[u] = tt++;
            }
            scanf("%d%d",&s,&t);
            spfa(s,t,n);
            init();
            for (int i = 0; i < tt; ++i)
            {
                int u = e[i].from,v = e[i].to,w = e[i].w;
                if (dis[u] + w == dis[v])
                {
                    addedge(u,v,1);
                }
            }
            int flow = sap(s,t,n);
            printf("%d
    ",flow);
        }
        return 0;
    }

    下面是TLE的spfa+dinic:

    //TLE spfa+dinic
    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN = 2010;
    const int MAXM = 120001;
    const int INF = 0x3f3f3f3f;
    int T,n,m;
    int s,t;
    struct Edge
    {
        int to,next,cap,flow;
    } edge[MAXM]; 
    int tol;
    int head[MAXN];
    void init()
    {
        tol = 2;
        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].flow = 0;
        edge[tol].next = head[u];
        head[u] = tol++;
        edge[tol].to = u;
        edge[tol].cap = rw;
        edge[tol].flow = 0;
        edge[tol].next = head[v];
        head[v] = tol++;
    }
    int Q[MAXN];
    int dep[MAXN],cur[MAXN],sta[MAXN];
    bool bfs(int s,int t,int n)
    {
        int front = 0,tail = 0;
        memset(dep,-1,sizeof(dep[0])*(n+1));
        dep[s] = 0;
        Q[tail++] = s;
        while(front < tail)
        {
            int u = Q[front++];
            for(int i = head[u]; i != - 1; i = edge[i].next)
            {
                int v = edge[i].to;
                if(edge[i].cap > edge[i].flow && dep[v] == - 1)
                {
                    dep[v] = dep[u] + 1;
                    if(v == t)
                        return true;
                    Q[tail++] = v;
                }
            }
        }
        return false;
    }
    int dinic(int s,int t,int n)
    {
        int maxflow = 0;
        while(bfs(s,t,n))
        {
            for(int i = 0; i < n; i++)
                cur[i] = head[i];
            int u = s, tail = 0;
            while(cur[s] != - 1)
            {
                if(u == t)
                {
                    int tp = INF;
                    for(int i = tail - 1; i >= 0; i--)
                        tp = min(tp,edge[sta[i]].cap - edge[sta[i]].flow)
                             ;
                    maxflow += tp;
                    for(int i = tail - 1; i >= 0; i--)
                    {
                        edge[sta[i]].flow += tp;
                        edge[sta[i]^1].flow -= tp;
                        if(edge[sta[i]].cap - edge[sta[i]].flow == 0)
                            tail = i;
                    }
                    u = edge[sta[tail]^1].to;
                }
                else if(cur[u] != - 1 && edge[cur[u]].cap > edge[cur[u]].flow && dep[u] + 1 == dep[edge[cur[u]].to])
                {
                    sta[tail++] = cur[u];
                    u = edge[cur[u]].to;
                }
                else
                {
                    while(u != s && cur[u] == - 1)
                        u = edge[sta[--tail]^1].to;
                    cur[u] = edge[cur[u]].next;
                }
            }
        }
        return maxflow;
    }
    
    struct K{
        int from,next,to,w;
    }e[MAXM];
    int dis[MAXN],vis[MAXN];
    
    queue <int> q;
    int c[MAXN];
    void spfa(int s,int t,int n){
        memset(dis,INF,sizeof(dis));
        memset(vis,0,sizeof(vis));
        memset(c,0,sizeof(c));
        vis[s] = true;
        dis[s] = 0;
        while(!q.empty()) q.pop();
        q.push(s);
        c[s] = 1;
        while(!q.empty()){
            int u = q.front();
            q.pop();
            vis[u] = false;
            for (int i = head[u];i != -1;i = e[i].next){
                int v = e[i].to,w = e[i].w;
                if (dis[v] > dis[u] + w){
                    dis[v] = dis[u] + w;
                    if (!vis[v]){
                        vis[v] = 1;
                        if (++c[v] > n) return;
                        q.push(v);
                    }
                }
            }
        }
    }
    
    int main(){
        scanf("%d",&T);
        while(T--){
            scanf("%d%d",&n,&m);
            int tt = 0;
            memset(head,-1,sizeof(head));
            for (int i = 0;i < m;++i){
                int u,v,w;
                scanf("%d%d%d",&u,&v,&w);
                if (u == v) continue;
                e[tt] = K{u,head[u],v,w};
                head[u] = tt++;
            }
            scanf("%d%d",&s,&t);
            spfa(s,t,n);
            init();
            for (int i = 0;i < tt;++i){
                int u = e[i].from,v = e[i].to,w = e[i].w;
                if (dis[u] + w == dis[v]){
                    addedge(u,v,1);
                }
            }
            int flow = dinic(s,t,n);
            printf("%d
    ",flow);
        }
        return 0;
    }
  • 相关阅读:
    ZZ
    Qt5获取网卡/IP等信息
    platforms
    [转]如何使用VS 2013發布一個可以在Windows XP中獨立運行的可執行文件
    spring cloud 服务提供者
    spring cloud: eureka搭建
    通过maven 上传jar 到nexus3,cong nexus3下载jar
    搭建turbine时 hystrix MaxConcurrentConnections reached 异常
    Zuul超时问题,微服务响应超时,zuul进行熔断
    微信公众号开发网址
  • 原文地址:https://www.cnblogs.com/mizersy/p/9522441.html
Copyright © 2011-2022 走看看