• BZOJ3876: [Ahoi2014]支线剧情


    题解:

    这貌似是很久以前的一个坑?

    边有下界,有源有汇,源向1连边,每个点都可以向汇连边。

    然后给点与点的边加上下界和费用,求最小可行费用流。

    但是!!!T了!!!因为每次增广只能+1容量,得增广5000+次。。。T_T

    再一次栽在费用流上!以后学了zkw再回来A这道题。

    挖坑待填。。。

     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 1000
    14 #define maxm 100000+5
    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=e[i].go;i;i=e[i].next,y=e[i].go)
    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,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 add(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 inline void insert(int x,int y,int l,int r,int c)
    42 {
    43     if(l){add(ss,y,l,c);add(x,tt,l,0);}
    44     add(x,y,r-l,c);
    45 }
    46 bool spfa()
    47 {
    48     for (int i=0;i<=t;i++){v[i]=0;d[i]=inf;}
    49     q.push(s);d[s]=0;v[s]=1;
    50     while(!q.empty())
    51     {
    52         int x=q.front();q.pop();v[x]=0;
    53         for (int i=head[x],y;i;i=e[i].next)
    54          if(e[i].v&&d[x]+e[i].c<d[y=e[i].go])
    55          {
    56             d[y]=d[x]+e[i].c;from[y]=i;
    57             if(!v[y]){v[y]=1;q.push(y);}
    58          }
    59     }
    60     return d[t]!=inf;
    61 }
    62 void mcf()
    63 {
    64     mincost=0;
    65     while(spfa())
    66     {
    67         int tmp=inf;
    68         for(int i=from[t];i;i=from[e[i].from]) tmp=min(tmp,e[i].v);
    69         mincost+=d[t]*tmp;
    70         for(int i=from[t];i;i=from[e[i].from]){e[i].v-=tmp;e[i^1].v+=tmp;}
    71     }
    72 }
    73 int main()
    74 {
    75     freopen("input.txt","r",stdin);
    76     freopen("output.txt","w",stdout);
    77     n=read();
    78     s=0;t=n+1;ss=t+1;tt=t+2;
    79     insert(s,1,0,inf,0);
    80     for1(i,n)
    81     {
    82         int tmp=read();
    83         for1(j,tmp)
    84         {
    85             int x=read(),y=read();
    86             insert(i,x,1,inf,y);
    87         }
    88         insert(i,t,0,inf,0);
    89     }
    90     insert(t,s,0,inf,0);
    91     s=ss;t=tt;
    92     mcf();
    93     printf("%d
    ",mincost);
    94     return 0;
    95 }
    View Code

    UPD:什么?我在学zkw?这明明是费用流+最大流。。。AC了好开心,被rank1怒艹

      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 1000
     14 #define maxm 100000+5
     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=e[i].go;i;i=e[i].next,y=e[i].go)
     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,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 inline void add(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 inline void insert(int x,int y,int l,int r,int c)
     42 {
     43     if(l){add(ss,y,l,c);add(x,tt,l,0);}
     44     add(x,y,r-l,c);
     45 }
     46 inline bool spfa()
     47 {
     48     for (int i=0;i<=t;i++){v[i]=0;d[i]=inf;}
     49     q.push(s);d[s]=0;v[s]=1;
     50     while(!q.empty())
     51     {
     52         int x=q.front();q.pop();v[x]=0;
     53         for (int i=head[x],y;i;i=e[i].next)
     54          if(e[i].v&&d[x]+e[i].c<d[y=e[i].go])
     55          {
     56             d[y]=d[x]+e[i].c;from[y]=i;
     57             if(!v[y]){v[y]=1;q.push(y);}
     58          }
     59     }
     60     return d[t]!=inf;
     61 }
     62 inline int dfs(int x,int f)
     63 {
     64     v[x]=1;
     65     if(x==t)return f;
     66     int used=0,tmp;
     67     for4(i,x)if(!v[y]&&e[i].v&&d[x]+e[i].c==d[y])
     68     {
     69         tmp=dfs(y,min(e[i].v,f-used));
     70         mincost+=tmp*e[i].c;
     71         e[i].v-=tmp;e[i^1].v+=tmp;
     72         used+=tmp;if(used==f)return f;
     73     }
     74     return used;
     75 }
     76 void mcf()
     77 {
     78     mincost=0;
     79     while(spfa())
     80     {
     81        v[t]=1;
     82        while(v[t])
     83        {
     84            memset(v,0,sizeof(v));
     85            dfs(s,inf);
     86        }
     87     }
     88 }
     89 int main()
     90 {
     91     freopen("input.txt","r",stdin);
     92     freopen("output.txt","w",stdout);
     93     n=read();
     94     s=0;t=n+1;ss=t+1;tt=t+2;
     95     insert(s,1,0,inf,0);
     96     for1(i,n)
     97     {
     98         int tmp=read();
     99         for1(j,tmp)
    100         {
    101             int x=read(),y=read();
    102             insert(i,x,1,inf,y);
    103         }
    104         insert(i,t,0,inf,0);
    105     }
    106     insert(t,s,0,inf,0);
    107     s=ss;t=tt;
    108     mcf();
    109     printf("%d
    ",mincost);
    110     return 0;
    111 }
    View Code

    3876: [Ahoi2014]支线剧情

    Time Limit: 10 Sec  Memory Limit: 256 MB
    Submit: 4  Solved: 1
    [Submit][Status]

    Description

    【故事背景】
    宅男JYY非常喜欢玩RPG游戏,比如仙剑,轩辕剑等等。不过JYY喜欢的并不是战斗场景,而是类似电视剧一般的充满恩怨情仇的剧情。这些游戏往往
    都有很多的支线剧情,现在JYY想花费最少的时间看完所有的支线剧情。
    【问题描述】
    JYY现在所玩的RPG游戏中,一共有N个剧情点,由1到N编号,第i个剧情点可以根据JYY的不同的选择,而经过不同的支线剧情,前往Ki种不同的新的剧情点。当然如果为0,则说明i号剧情点是游戏的一个结局了。
    JYY观看一个支线剧情需要一定的时间。JYY一开始处在1号剧情点,也就是游戏的开始。显然任何一个剧情点都是从1号剧情点可达的。此外,随着游戏的进行,剧情是不可逆的。所以游戏保证从任意剧情点出发,都不能再回到这个剧情点。由于JYY过度使用修改器,导致游戏的“存档”和“读档”功能损坏了,
    所以JYY要想回到之前的剧情点,唯一的方法就是退出当前游戏,并开始新的游戏,也就是回到1号剧情点。JYY可以在任何时刻退出游戏并重新开始。不断开始新的游戏重复观看已经看过的剧情是很痛苦,JYY希望花费最少的时间,看完所有不同的支线剧情。

    Input

    输入一行包含一个正整数N。
    接下来N行,第i行为i号剧情点的信息;
    第一个整数为,接下来个整数对,Bij和Tij,表示从剧情点i可以前往剧
    情点,并且观看这段支线剧情需要花费的时间。
     

    Output

     输出一行包含一个整数,表示JYY看完所有支线剧情所需要的最少时间。

     
     
     

    Sample Input

    6
    2 2 1 3 2
    2 4 3 5 4
    2 5 5 6 6
    0
    0
    0

    Sample Output

    24

    HINT

     JYY需要重新开始3次游戏,加上一开始的一次游戏,4次游戏的进程是


    1->2->4,1->2->5,1->3->5和1->3->6。

     

    对于100%的数据满足N<=300,0<=Ki<=50,1<=Tij<=300,Sigma(Ki)<=5000

    Source

  • 相关阅读:
    第 9 章
    第 8 章
    第 7 章
    第 6 章
    第 5 章
    第 4 章
    跳舞链解数独
    minic 类型声明与变量定义句型处理
    minic 动作句型处理
    minic 符号表
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/4230305.html
Copyright © 2020-2023  润新知