zoukankan      html  css  js  c++  java
  • BZOJ2055: 80人环游世界

    题解:

    总算A掉了,各种蛋疼。。。

    int main()
    {
        freopen("input.txt","r",stdin);
        freopen("output.txt","w",stdout);
        n=read();m=read();s=0;t=2*n+m+1;ss=t+1;tt=t+2;sss=tt+1;
        insert(s,sss,0,m,0);
        for1(i,n)insert(sss,i,0,inf,0);
        for1(i,n){int x=read();insert(i,i+n,x,x,0);}
        for1(i,n)for2(j,i+1,n){int x=read();if(x!=-1)insert(i+n,j,0,inf,x);}
        for1(i,n)insert(i+n,t,0,inf,0);
        insert(t,s,0,inf,0);
        mcf();
        printf("%d
    ",mincost);
        return 0;
    }

    s是附加源,sss是真正的源,t是真正的汇。这样构图就好了,但我们还有下界限制,那再来个ss,tt。。。居然还是费用流。。。然后这题就做完了
    因为我们只需要最小费用,所以我们只需求出可行流&最小费用即可。

    关于下界的处理我直接写在insert函数里。。。导致慢成翔。。。

    代码:

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<iostream>
     7 #include<vector>
     8 #include<map>
     9 #include<set>
    10 #include<queue>
    11 #include<string>
    12 #define inf 1000000000
    13 #define maxn 200000
    14 #define maxm 200000
    15 #define eps 1e-10
    16 #define ll long long
    17 #define pa pair<int,int>
    18 #define for0(i,n) for(int i=0;i<=(n);i++)
    19 #define for1(i,n) for(int i=1;i<=(n);i++)
    20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
    21 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
    22 #define for4(i,x) for(int i=head[x],y;i;i=e[i].next)
    23 #define mod 1000000007
    24 using namespace std;
    25 inline int read()
    26 {
    27     int x=0,f=1;char ch=getchar();
    28     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    29     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
    30     return x*f;
    31 }
    32 int n,m,k,mincost,tot=1,s,t,ss,tt,sss,head[maxn],d[maxn],from[2*maxm];
    33 bool v[maxn];
    34 queue<int>q;
    35 struct edge{int from,go,next,v,c;}e[2*maxm];
    36 void ins(int x,int y,int v,int c)
    37 {
    38     e[++tot]=(edge){x,y,head[x],v,c};head[x]=tot;
    39     e[++tot]=(edge){y,x,head[y],0,-c};head[y]=tot;
    40 }
    41 void insert(int x,int y,int l,int r,int c)
    42 {
    43     ins(ss,y,l,c);ins(x,tt,l,0);ins(x,y,r-l,c);
    44 }
    45 bool spfa()
    46 {
    47     for (int i=0;i<=sss;i++){v[i]=0;d[i]=inf;}
    48     q.push(ss);d[ss]=0;v[ss]=1;
    49     while(!q.empty())
    50     {
    51         int x=q.front();q.pop();v[x]=0;
    52         for (int i=head[x],y;i;i=e[i].next)
    53          if(e[i].v&&d[x]+e[i].c<d[y=e[i].go])
    54          {
    55             d[y]=d[x]+e[i].c;from[y]=i;
    56             if(!v[y]){v[y]=1;q.push(y);}
    57          }
    58     }
    59     return d[tt]!=inf;
    60 }
    61 void mcf()
    62 {
    63     mincost=0;
    64     while(spfa())
    65     {
    66         int tmp=inf;
    67         for(int i=from[tt];i;i=from[e[i].from]) tmp=min(tmp,e[i].v);
    68         mincost+=d[tt]*tmp;
    69         for(int i=from[tt];i;i=from[e[i].from]){e[i].v-=tmp;e[i^1].v+=tmp;}
    70     }
    71 }
    72 int main()
    73 {
    74     freopen("input.txt","r",stdin);
    75     freopen("output.txt","w",stdout);
    76     n=read();m=read();s=0;t=2*n+m+1;ss=t+1;tt=t+2;sss=tt+1;
    77     insert(s,sss,0,m,0);
    78     for1(i,n)insert(sss,i,0,inf,0);
    79     for1(i,n){int x=read();insert(i,i+n,x,x,0);}
    80     for1(i,n)for2(j,i+1,n){int x=read();if(x!=-1)insert(i+n,j,0,inf,x);}
    81     for1(i,n)insert(i+n,t,0,inf,0);
    82     insert(t,s,0,inf,0);
    83     mcf();
    84     printf("%d
    ",mincost);
    85     return 0;
    86 }
    View Code

     UPD:把边合并了之后用时成了1/4

    代码:

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<iostream>
     7 #include<vector>
     8 #include<map>
     9 #include<set>
    10 #include<queue>
    11 #include<string>
    12 #define inf 1000000000
    13 #define maxn 200000
    14 #define maxm 200000
    15 #define eps 1e-10
    16 #define ll long long
    17 #define pa pair<int,int>
    18 #define for0(i,n) for(int i=0;i<=(n);i++)
    19 #define for1(i,n) for(int i=1;i<=(n);i++)
    20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
    21 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
    22 #define for4(i,x) for(int i=head[x],y;i;i=e[i].next)
    23 #define mod 1000000007
    24 using namespace std;
    25 inline int read()
    26 {
    27     int x=0,f=1;char ch=getchar();
    28     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    29     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
    30     return x*f;
    31 }
    32 int n,m,k,mincost,tot=1,s,t,ss,tt,sss,head[maxn],d[maxn],from[2*maxm],in[maxn];
    33 bool v[maxn];
    34 queue<int>q;
    35 struct edge{int from,go,next,v,c;}e[2*maxm];
    36 void ins(int x,int y,int v,int c)
    37 {
    38     e[++tot]=(edge){x,y,head[x],v,c};head[x]=tot;
    39     e[++tot]=(edge){y,x,head[y],0,-c};head[y]=tot;
    40 }
    41 void insert(int x,int y,int l,int r,int c)
    42 {
    43     in[y]+=l;
    44     in[x]-=l;
    45     ins(x,y,r-l,c);
    46 }
    47 void build()
    48 {
    49     for0(i,sss)if(in[i]>0)ins(ss,i,in[i],0);
    50     else if(in[i]<0)ins(i,tt,-in[i],0);
    51 }
    52 bool spfa()
    53 {
    54     for (int i=0;i<=sss;i++){v[i]=0;d[i]=inf;}
    55     q.push(ss);d[ss]=0;v[ss]=1;
    56     while(!q.empty())
    57     {
    58         int x=q.front();q.pop();v[x]=0;
    59         for (int i=head[x],y;i;i=e[i].next)
    60          if(e[i].v&&d[x]+e[i].c<d[y=e[i].go])
    61          {
    62             d[y]=d[x]+e[i].c;from[y]=i;
    63             if(!v[y]){v[y]=1;q.push(y);}
    64          }
    65     }
    66     return d[tt]!=inf;
    67 }
    68 void mcf()
    69 {
    70     mincost=0;
    71     while(spfa())
    72     {
    73         int tmp=inf;
    74         for(int i=from[tt];i;i=from[e[i].from]) tmp=min(tmp,e[i].v);
    75         mincost+=d[tt]*tmp;
    76         for(int i=from[tt];i;i=from[e[i].from]){e[i].v-=tmp;e[i^1].v+=tmp;}
    77     }
    78 }
    79 int main()
    80 {
    81     freopen("input.txt","r",stdin);
    82     freopen("output.txt","w",stdout);
    83     n=read();m=read();s=0;t=2*n+m+1;ss=t+1;tt=t+2;sss=tt+1;
    84     insert(s,sss,0,m,0);
    85     for1(i,n)insert(sss,i,0,inf,0);
    86     for1(i,n){int x=read();insert(i,i+n,x,x,0);}
    87     for1(i,n)for2(j,i+1,n){int x=read();if(x!=-1)insert(i+n,j,0,inf,x);}
    88     for1(i,n)insert(i+n,t,0,inf,0);
    89     insert(t,s,0,inf,0);
    90     build();
    91     mcf();
    92     printf("%d
    ",mincost);
    93     return 0;
    94 }
    View Code

    2055: 80人环游世界

    Time Limit: 10 Sec  Memory Limit: 64 MB
    Submit: 116  Solved: 75
    [Submit][Status]

    Description

    Input

    第一行两个正整数N,M。第二行有N个不大于M正整数,分别表示V1,V2......VN。接下来有N ¡ 1行。第i行有N ¡ i个整数,该行的第j个数表示从第i个国家到第i + j个国家的机票费(如果该值等于¡1则表示这两个国家间没有通航)。

    Output

    在第一行输出最少的总费用。

    Sample Input

    6 3
    2 1 3 1 2 1
    2 6 8 5 0
    8 2 4 1
    6 1 0
    4 -1
    4

    Sample Output

    27

    HINT

    1<= N < =100 1<= M <= 79

  • 相关阅读:
    条件语句的用法
    PHP取得当前文档所在的目录
    郁闷,一个语句调试很久
    PHP图片上传加水印(转)
    PHP多行多列分页
    ASP得到当前文件所在目录
    “树人杯”暨第三届辽宁科技大学校园程序设计竞赛正赛D IP检测(绿)
    “树人杯”暨第三届辽宁科技大学校园程序设计竞赛正赛E 成绩统计图(红)
    [面试备] 暴搜 or 二分图的经典升级 : hdu 1045 Fire Net 示例 [ 讲解之用 ]
    《C++ Primer》 第04章 [ 数组和指针 ]
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/4176415.html
Copyright © 2011-2022 走看看