zoukankan      html  css  js  c++  java
  • HDU-3416

    https://vjudge.net/problem/HDU-3416

    题意:给出一个图,有多少个边不重复的最短路。

    思路:先用dijkstar从s跑最短路,然后再从t倒着跑一边(注意该题是有向图,我一开始当成无向图了......),从而通过d1[u[i]]+d2[v[i]]+c[i]=d1[t]确定哪一条边属于最短路,然后把属于最短路的边建图跑最大流,每条边的容量为1。

    #include<bits/stdc++.h>
    #define _for(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    typedef long long ll;
    const int mod =1e6+7;
    double esp=1e-6;
    int INF =0x3f3f3f3f;
    //const int inf = 1<<28;
    const int MAXN=200000+10;
    const int inf=0x3f3f3f3f;
    using namespace std;
    typedef long long LL;
    int n,m,u[MAXN],v[MAXN],c[MAXN];
    ll dis1[MAXN],dis2[MAXN];
    struct node
    {
        ll d,x;
        bool operator <(const node &p)const
        {
            return d>p.d;
        }
    };
    typedef pair<int,int> P;
    vector <P> GG[MAXN];
    priority_queue<node> Q;
    bool vis[MAXN];
    void dijkstar(int s,ll* d1)
    {
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++)d1[i]=INF;
        d1[s]=0;
        Q.push((node){0,s});
        while(!Q.empty())
        {
            node tmp=Q.top();
            Q.pop();
            int u=tmp.x;
            if(vis[u])continue;
            vis[u]=1;
            for(int i=0;i<GG[u].size();i++)
            {
                int v=GG[u][i].first;
                int w=GG[u][i].second;
                if(d1[v]>d1[u]+w)
                {
                    d1[v]=d1[u]+w;
                    //printf("%d %d
    ",v,d[v]);
                    Q.push((node){d1[v],v});
                }
            }
        }
        return ;
    }
    struct edge
    {
        int from,to,cap,flow;
    };
    vector<edge> edges;
    vector<int> G[MAXN];
    void add(int from,int to,int cap)
    {
        edges.push_back((edge){from,to,cap,0});
        edges.push_back((edge){to,from,0,0});
        int m=edges.size();
        G[from].push_back(m-2);
        G[to].push_back(m-1);
    }
    bool vis1[MAXN];
    int cur[MAXN];
    int d[MAXN],s,t;
    bool bfs()
    {
        memset(vis1,0,sizeof(vis1));
        queue<int>QQ;
        QQ.push(s);
        vis1[s]=1;
        while(!QQ.empty())
        {
            int x=QQ.front();
            QQ.pop();
            for(int i=0;i<G[x].size();i++)
            {
                edge &e=edges[G[x][i]];
                if(!vis1[e.to]&&e.cap>e.flow)
                {
                    vis1[e.to]=1;
                    d[e.to]=d[x]+1;
                    QQ.push(e.to);
                }
            }
        }
        return vis1[t];
    }
    int dfs(int x,int a)
    {
        if(x==t||a==0)
            return a;
        int flow=0,f;
        for(int& i=cur[x];i<G[x].size();i++)
        {
            edge &e=edges[G[x][i]];
            if(d[x]+1==d[e.to]&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0)
            {
                e.flow+=f;
                edges[G[x][i]^1].flow-=f;
                flow+=f;
                a-=f;
                if(a==0)break;
            }
        }
        return flow;
    }
    int max_Flow(int s,int t)
    {
        int flow=0;
        while(bfs())
        {
            //printf("**
    ");
            memset(cur,0,sizeof(cur));
            flow+=dfs(s,INF);
        }
        return flow;
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        {
            while(T--)
        {
            scanf("%d%d",&n,&m);
            for(int i=1;i<=m;i++)
            {
                scanf("%d%d%d",&u[i],&v[i],&c[i]);
                GG[u[i]].push_back(P(v[i],c[i]));
            }
            scanf("%d%d",&s,&t);
            dijkstar(s,dis1);
            //while(!Q.empty())Q.pop();
            for(int i=1;i<=n;i++)GG[i].clear();
            for(int i=1;i<=m;i++)GG[v[i]].push_back(P(u[i],c[i]));
            dijkstar(t,dis2);
            //for(int i=1;i<=n;i++)printf("%lld %lld
    ",dis1[i],dis2[i]);
            for(int i=1;i<=m;i++)
            {
                if(dis1[u[i]]+c[i]+dis2[v[i]]==dis1[t])
                {
                    add(u[i],v[i],1);
                    //printf("%d %d
    ",u[i],v[i]);
                }
    
            }
            cout<<max_Flow(s,t)<<endl;
            for(int i=1;i<=n;i++)
            {
                G[i].clear();
                GG[i].clear();
            }
        }
        }
    
        return 0;
    }
  • 相关阅读:
    poj 3304 Segments 直线 线段求交
    poj 1077 Eight 八数码 A*算法
    UESTC 1447 Area 凸包+旋转卡壳 求最大四边形面积
    ACM计算几何题目推荐(第二期)
    poj 2398 Toy Storage 叉乘
    ACM计算几何题目推荐 (第一期)
    (转载)Telnet协议详解及使用C# 用Socket 编程来实现Telnet协议
    jquery 表情编辑器
    (读书笔记)Asp.net Mvc 与WebForm 混合开发
    (转载)精简说明C#最基本的Socket编程示例
  • 原文地址:https://www.cnblogs.com/kayiko/p/12343571.html
Copyright © 2011-2022 走看看