• BZOJ 1927 星际竞速


    http://www.lydsy.com/JudgeOnline/problem.php?id=1927

    思路:把一个点拆成两个点,

    S->i 费用0,流量1 (代表这个点可以移动到其他点所必备的流量)

    i+n->T 费用0,流量1 (每个点都必须要走过)

    u->v+n 费用w,流量1  (代表可以移动到那个点)

    S->i+n 费用a[i],流量1 (代表从这个点瞬移)

     1 #include<algorithm>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<iostream>
     6 int tot,go[200005],next[200005],first[200005],cost[200005],flow[200005];
     7 int op[200005],dis[200005],c[200005],vis[200005],edge[200005],from[200005];
     8 int S,T,n,m,ans;
     9 int read(){
    10     char ch=getchar();int t=0,f=1;
    11     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    12     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
    13     return t*f;
    14 }
    15 void insert(int x,int y,int z,int l){
    16     tot++;
    17     go[tot]=y;
    18     next[tot]=first[x];
    19     first[x]=tot;
    20     flow[tot]=z;
    21     cost[tot]=l;
    22 }
    23 void add(int x,int y,int z,int l){
    24     insert(x,y,z,l);op[tot]=tot+1;
    25     insert(y,x,0,-l);op[tot]=tot-1;
    26 }
    27 bool spfa(){
    28     for (int i=S;i<=T;i++)
    29      dis[i]=0x3f3f3f3f,vis[i]=0;
    30     int h=1,t=1;c[1]=S;vis[S]=1;dis[S]=0;
    31     while (h<=t){
    32         int now=c[h++];
    33         for (int i=first[now];i;i=next[i]){
    34             int pur=go[i];
    35             if (dis[pur]>dis[now]+cost[i]&&flow[i]){
    36                 dis[pur]=dis[now]+cost[i];
    37                 edge[pur]=i;
    38                 from[pur]=now;
    39                 if (vis[pur]) continue;
    40                 vis[pur]=1;
    41                 c[++t]=pur;
    42             }
    43         }
    44         vis[now]=0;
    45     }
    46     return dis[T]!=0x3f3f3f3f;
    47 }
    48 void updata(){
    49     int mn=0x7ffffff;
    50     for (int i=T;i!=S;i=from[i]){
    51         mn=std::min(mn,flow[edge[i]]);
    52     }
    53     for (int i=T;i!=S;i=from[i]){
    54         ans+=mn*cost[edge[i]];
    55         flow[edge[i]]-=mn;
    56         flow[op[edge[i]]]+=mn;
    57     }
    58 }
    59 int main(){
    60     n=read();m=read();
    61     S=0;T=n+n+1;
    62     for (int i=1;i<=n;i++)
    63      add(S,i,1,0);
    64     for (int i=1;i<=n;i++){
    65         int x=read();
    66         add(S,i+n,1,x);
    67     }
    68     for (int i=1;i<=n;i++)
    69         add(i+n,T,1,0);
    70     while (m--){
    71         int u=read(),v=read(),w=read();
    72         if (u>v) std::swap(u,v);
    73         add(u,v+n,1,w);
    74     }    
    75     ans=0;
    76     while (spfa()) updata();
    77     printf("%d
    ",ans);
    78 }
  • 相关阅读:
    Elementary Methods in Number Theory Exercise 1.2.25
    Elementary Methods in Number Theory Exercise 1.2.14
    图解欧几里德算法
    图解欧几里德算法
    Elementary Methods in Number Theory Exercise 1.2.14
    Android中的长度单位详解(dp、sp、px、in、pt、mm)
    分享下多年积累的对JAVA程序员成长之路的总结
    android异常之都是deamon惹的祸The connection to adb is down, and a severe error has occured.
    TomatoCartv1.1.8.2部署时报错
    JavaScript浏览器对象之二Document对象
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5615288.html
Copyright © 2020-2023  润新知