zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    [ 原创 ] Oracle存储过程中使用游标进行多行数据输出
    [ 原创 ] Python解压版安装配置教程
    [ 转载 ] ORACLE存储过程
    [ 转载 ] Oracle存储过程及函数的练习题
    [ 原创 ] Oracle数据库一些基本命令
    [ 转载 ] Linux CentOS 查看操作系统版本信息
    [ 转载 ] Android开发中如何做单元测试
    [ 转载 ] 关于conn /as sysdba 无需密码直接可以连接的疑问
    [ 转载 ] oracle如何查看当前有哪些用户连接到数据库
    [ 转载 ] Oracle 内存(SGA,PGA)详细介绍
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5615288.html
Copyright © 2011-2022 走看看