最小费用最大流【Our Journey of Dalian Ends】【Our Journey of Xian Ends】2017青岛区域赛J

1 篇文章 0 订阅
1 篇文章 0 订阅

【Our Journey of Dalian Ends】

#include<algorithm>
#include<vector>
#include<iostream>
#include<math.h>
#include<cstring>
#include<string>
#include<stack>
#include<map>
#include<set>
#include<unordered_map>
#include<queue>

#define qcin; ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define pb push_back
#define clr(x) memset(x,0,sizeof x)
#define fmax(x) memset(x,0x3f,sizeof x)
#define finit(x) memset(x,-1,sizeof x)

#define dis(l,r) r-l+1
#define gstr(str) scanf("%s",str)
#define glen(str) strlen(str)
using namespace std;

typedef long long ll;


const int maxn = 100000+10;
const int inf = 0x3f3f3f3f;

typedef int arr[maxn];
typedef char str[maxn];
void file(int x){if(x&&fopen("123.in","r")){freopen("123.in","r",stdin);}}

const int mod=1e9+7;

struct Edge{
    int to,next,cap,flow,cost;
}edge[maxn];

int head[maxn],pre[maxn],dis[maxn],vis[maxn];
int tot;

int n,m,x,cnt,st,en,L,u,v,q,cst,len,t;

const double pi=acos(-1);

unordered_map<string,int>M;
string su,sv;

int e[maxn][3];

int gid(string x){
    if(M.find(x)!=M.end())return M[x];
    M[x]=++cnt;
    return M[x];
}

void addedge(int u,int v,int cap,int cost){
    edge[tot].to=v;
    edge[tot].cap=cap;
    edge[tot].cost=cost;
    edge[tot].flow=0;
    edge[tot].next=head[u];
    head[u]=tot++;

    edge[tot].to=u;
    edge[tot].cap=0;
    edge[tot].cost=-cost;
    edge[tot].flow=0;
    edge[tot].next=head[v];
    head[v]=tot++;
}

int spfa(int st,int en){
    queue<int>q;
    for(int i=0;i<2*cnt+5;i++){
        dis[i]=inf;
        vis[i]=false;
        pre[i]=-1;
    }
    dis[st]=0;
    vis[st]=1;
    q.push(st);
    while(q.size()){
        int u=q.front();
        q.pop();
        vis[u]=0;
        for(int i=head[u];~i;i=edge[i].next){
            int v=edge[i].to;
            if(edge[i].cap>edge[i].flow&&dis[v]>dis[u]+edge[i].cost){
                dis[v]=dis[u]+edge[i].cost;
                pre[v]=i;
                if(!vis[v]){

                    vis[v]=1;
                    q.push(v);
                }
            }
        }
    }
    if(~pre[en])return 1;
    else return 0;
}
int c_f(int st,int en,int&cost){
    int flow=0;
    cost=0;
    while(spfa(st,en)){
        int mi=inf;
        for(int i=pre[en];~i;i=pre[edge[i^1].to]){
            if(mi>edge[i].cap-edge[i].flow)
                mi=edge[i].cap-edge[i].flow;
        }
        for(int i=pre[en];~i;i=pre[edge[i^1].to]){
            edge[i].flow+=mi;
            edge[i^1].flow-=mi;
            cost+=edge[i].cost*mi;
        }
        flow+=mi;
    }
    return flow;
}



int main(){
    file(1);
    qcin;
    for(cin>>t;t--;){
        M.clear();
        M["Dalian"]=1;
        M["Shanghai"]=2;
        M["Xian"]=3;
        cnt=3;
        cin>>m;
        tot=0;
        finit(head);
        for(int i=0;i<m;i++){
            cin>>su>>sv>>cst;
            e[i][0]=gid(su);
            e[i][1]=gid(sv);
            e[i][2]=cst;
        }
        st=2*cnt+1;
        en=2*cnt+2;
        addedge(st,2,2,0);
        addedge(1+cnt,en,1,0);
        addedge(3+cnt,en,1,0);
        for(int i=1;i<=cnt;i++){
            if(i==2)addedge(i,i+cnt,2,0);
            else addedge(i,i+cnt,1,0);
        }
        for(int i=0;i<m;i++){
            addedge(e[i][0]+cnt,e[i][1],inf,e[i][2]);
            addedge(e[i][1]+cnt,e[i][0],inf,e[i][2]);
        }
        int cost=0,flow;
        flow=c_f(st,en,cost);
        if(flow!=2)cout<<-1<<endl;
        else cout<<cost<<endl;
    }
    return 0;
}

【Our Journey of Xian Ends】

#include<algorithm>
#include<vector>
#include<iostream>
#include<math.h>
#include<cstring>
#include<string>
#include<stack>
#include<map>
#include<set>
#include<unordered_map>
#include<queue>

#define qcin; ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define pb push_back
#define clr(x) memset(x,0,sizeof x)
#define fmax(x) memset(x,0x3f,sizeof x)
#define finit(x) memset(x,-1,sizeof x)

#define dis(l,r) r-l+1
#define gstr(str) scanf("%s",str)
#define glen(str) strlen(str)
using namespace std;

typedef long long ll;


const int maxn = 100000+10;
const int inf = 0x3f3f3f3f;

typedef int arr[maxn];
typedef char str[maxn];
void file(int x){if(x&&fopen("123.in","r")){freopen("123.in","r",stdin);}}

const int mod=1e9+7;

struct Edge{
    int to,next,cap,flow,cost;
}edge[maxn];

int head[maxn],pre[maxn],dis[maxn],vis[maxn];
int tot;

int n,m,x,cnt,st,en,L,u,v,q,cst,len,t;

const double pi=acos(-1);

unordered_map<string,int>M;
string su,sv;

int e[maxn][3];

int gid(string x){
    if(M.find(x)!=M.end())return M[x];
    M[x]=++cnt;
    return M[x];
}

void addedge(int u,int v,int cap,int cost){
    edge[tot].to=v;
    edge[tot].cap=cap;
    edge[tot].cost=cost;
    edge[tot].flow=0;
    edge[tot].next=head[u];
    head[u]=tot++;

    edge[tot].to=u;
    edge[tot].cap=0;
    edge[tot].cost=-cost;
    edge[tot].flow=0;
    edge[tot].next=head[v];
    head[v]=tot++;
}

int spfa(int st,int en){
    queue<int>q;
    for(int i=0;i<2*cnt+5;i++){
        dis[i]=inf;
        vis[i]=false;
        pre[i]=-1;
    }
    dis[st]=0;
    vis[st]=1;
    q.push(st);
    while(q.size()){
        int u=q.front();
        q.pop();
        vis[u]=0;
        for(int i=head[u];~i;i=edge[i].next){
            int v=edge[i].to;
            if(edge[i].cap>edge[i].flow&&dis[v]>dis[u]+edge[i].cost){
                dis[v]=dis[u]+edge[i].cost;
                pre[v]=i;
                if(!vis[v]){

                    vis[v]=1;
                    q.push(v);
                }
            }
        }
    }
    if(~pre[en])return 1;
    else return 0;
}
int c_f(int st,int en,int&cost){
    int flow=0;
    cost=0;
    while(spfa(st,en)){
        int mi=inf;
        for(int i=pre[en];~i;i=pre[edge[i^1].to]){
            if(mi>edge[i].cap-edge[i].flow)
                mi=edge[i].cap-edge[i].flow;
        }
        for(int i=pre[en];~i;i=pre[edge[i^1].to]){
            edge[i].flow+=mi;
            edge[i^1].flow-=mi;
            cost+=edge[i].cost*mi;
        }
        flow+=mi;
    }
    return flow;
}



int main(){
    file(1);
    qcin;
    for(cin>>t;t--;){
        M.clear();
        M["Xian"]=1;
        M["Hongqiao"]=2;
        M["Pudong"]=3;
        M["Qingdao"]=4;
        cnt=4;
        cin>>m;
        tot=0;
        finit(head);
        for(int i=0;i<m;i++){
            cin>>su>>sv>>cst;
            e[i][0]=gid(su);
            e[i][1]=gid(sv);
            e[i][2]=cst;
        }
        st=2*cnt+1;
        en=2*cnt+2;
        addedge(st,1,1,0);
        addedge(st,4,2,0);
        addedge(2+cnt,en,2,0);
        addedge(3+cnt,en,1,0);

        for(int i=1;i<=cnt;i++){
            if(i==2||i==4)addedge(i,i+cnt,2,0);
            else addedge(i,i+cnt,1,0);
        }
        for(int i=0;i<m;i++){
            addedge(e[i][0]+cnt,e[i][1],inf,e[i][2]);
            addedge(e[i][1]+cnt,e[i][0],inf,e[i][2]);
        }
        int cost=0,flow;
        flow=c_f(st,en,cost);
        if(flow!=3)cout<<-1<<endl;
        else cout<<cost<<endl;

    }
    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值