码迷,mamicode.com
首页 > 其他好文 > 详细

HDU-3416

时间:2020-02-22 00:31:52      阅读:63      评论:0      收藏:0      [点我收藏+]

标签:turn   tps   scanf   --   mod   include   通过   开始   cout   

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\n",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("**\n");
        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\n",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\n",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;
}

 

HDU-3416

标签:turn   tps   scanf   --   mod   include   通过   开始   cout   

原文地址:https://www.cnblogs.com/kayiko/p/12343571.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!