• bzoj1927[Sdoi2010]星际竞速


    bzoj1927[Sdoi2010]星际竞速

    题意:

    赛车大赛的赛场由N颗行星和M条双向星际航路构成,其中每颗行星都有一个不同的引力值。大赛要求车手们从一颗与这N颗行星之间没有任何航路的天体出发,访问这N颗行星每颗恰好一次。赛车超能电驴在高速航行模式下,沿星际航路航行,但只能由每个星球飞往引力比它大的星球。在能力爆发模式下,超能电驴在经过一段时间的定位之后,能瞬间移动到任意一个行星。求完成比赛最短时间。N≤800,M≤15000

    题解:

    费用流。对每个点拆成X,Y两个点,源向每个Y点连边,流量为1,费用为对这个行星的定位时间,表示直接经过这个行星。源再向每个X点连边流量1,费用0,每个Y点向汇连边,流量1,费用0。X与Y之间按“星际航路”连边,表示从X点到Y点。我们不关心从哪里到这个行星再到哪里去,我们只考虑每个行星只能经过一次。反思:本智障一开始看不懂任何题解,后来发现自己以为是能力爆发模式需要受引力限制,不审题退役QAQ

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <queue>
     5 #define inc(i,j,k) for(int i=j;i<=k;i++)
     6 #define maxn 2000
     7 #define INF 0x3fffffff
     8 using namespace std;
     9 
    10 struct e{int f,t,c,w,n;}; e es[maxn*40]; int ess,g[maxn];
    11 inline void pe(int f,int t,int c,int w){
    12     es[++ess]=(e){f,t,c,w,g[f]}; g[f]=ess; es[++ess]=(e){t,f,0,-w,g[t]}; g[t]=ess;
    13 }
    14 void init(){ess=-1; memset(g,-1,sizeof(g));}
    15 int d[maxn],fr[maxn]; bool inq[maxn]; queue <int> q;
    16 bool spfa(int s,int t){
    17     while(!q.empty())q.pop(); memset(inq,0,sizeof(inq)); memset(d,-1,sizeof(d));
    18     inq[s]=1; d[s]=0; q.push(s); fr[s]=-1;
    19     while(! q.empty()){
    20         int x=q.front(); q.pop(); inq[x]=0;
    21         for(int i=g[x];i!=-1;i=es[i].n)if(es[i].c&&(d[es[i].t]==-1||d[es[i].t]>d[x]+es[i].w)){
    22             d[es[i].t]=d[x]+es[i].w; fr[es[i].t]=i; if(!inq[es[i].t])inq[es[i].t]=1,q.push(es[i].t);
    23         }
    24     }
    25     return d[t]!=-1;
    26 }
    27 int advanced(int s,int t){
    28     int a=INF,c=0;
    29     for(int i=fr[t];i!=-1;i=fr[es[i].f])a=min(a,es[i].c);
    30     for(int i=fr[t];i!=-1;i=fr[es[i].f])es[i].c-=a,es[i^1].c+=a,c+=(a*es[i].w);
    31     return c;
    32 }
    33 int maxflowmincost(int s,int t){
    34     int c=0; while(spfa(s,t))c+=advanced(s,t); return c;
    35 }
    36 int n,m,s,t;
    37 int main(){
    38     scanf("%d%d",&n,&m); s=0; t=2*n+1; init();
    39     inc(i,1,n){int a; scanf("%d",&a); pe(s,i+n,1,a);}
    40     inc(i,1,m){int a,b,c; scanf("%d%d%d",&a,&b,&c); pe(min(a,b),max(a,b)+n,1,c);}
    41     inc(i,1,n)pe(s,i,1,0),pe(i+n,t,1,0);
    42     printf("%d",maxflowmincost(s,t)); return 0;
    43 }

    20160527

  • 相关阅读:
    c++ 设计模式6 (Decorator 装饰模式)
    c++ 设计模式7 (Bridge 桥模式)
    c++ 设计模式8 (Factory Method 工厂方法)
    c++ 设计模式9 (Abstract Factory 抽象工厂模式)
    C++类设计2(Class with pointer members)
    C++类设计1(Class without pointer members)
    算法总结—链表
    C++对象内存模型1(堆栈模型)
    PHP 页面编码声明方法详解(header或meta)
    php变量与数组相互转换的方法(extract与compact
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/5698480.html
Copyright © 2020-2023  润新知