zoukankan      html  css  js  c++  java
  • C++之路进阶——codevs2306(晨跑)

    2306 晨跑

     

    2009年省队选拔赛山东

     时间限制: 1 s
     空间限制: 256000 KB
     题目等级 : 大师 Master
     
     
     
    题目描述 Description

    Elaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧撑、仰卧起坐等等,不过到目前为止,他坚持下来的只有晨跑。

    现在给出一张学校附近的地图,这张地图中包含N个十字路口和M条街道,Elaxia只能从一个十字路口跑向另外一个十字路口,街道之间只在十字路口处相交。Elaxia每天从寝室出发跑到学校,保证寝室编号为1,学校编号为N。

    Elaxia的晨跑计划是按周期(包含若干天)进行的,由于他不喜欢走重复的路线,所以在一个周期内,每天的晨跑路线都不会相交(在十字路口处),寝室和学校不算十字路口。Elaxia耐力不太好,他希望在一个周期内跑的路程尽量短,但是又希望训练周期包含的天数尽量长。

    除了练空手道,Elaxia其他时间都花在了学习和找MM上面,所有他想请你帮忙为他设计一套满足他要求的晨跑计划。

    输入描述 Input Description

    第一行:两个数N,M。表示十字路口数和街道数。

    接下来M行,每行3个数a,b,c,表示路口a和路口b之间有条长度为c的街道(单向)。

    输出描述 Output Description

    两个数,第一个数为最长周期的天数,第二个数为满足最长天数的条件下最短的路程长度。

    样例输入 Sample Input

    7 10

    1 2 1

    1 3 1

    2 4 1

    3 4 1

    4 5 1

    4 6 1

    2 5 5

    3 6 6

    5 7 1

    6 7 1

    样例输出 Sample Output

    2 11

    数据范围及提示 Data Size & Hint

    对于30%的数据,N ≤ 20,M ≤ 120。

    对于100%的数据,N ≤ 200,M ≤ 20000。

    题解:

      裸的最大流和最小费用最大流。

    代码:

       

      1 #include<cstdio>
      2 #include<queue>
      3 #include<algorithm>
      4 #include<iostream>
      5 #include<cstring>
      6 #define maxn 1010
      7 #define S 1
      8 #define T n*2
      9 #define INF 0x7fffffff
     10 
     11 using namespace std; 
     12 
     13 int head[maxn],n,m,dis[maxn],inq[maxn],from[maxn],cnt=1,ans;
     14 
     15 struct ss
     16    {
     17         int to;
     18         int next;
     19         int c;
     20         int w;
     21         int from;
     22         int edge;
     23    }e[20010<<2];
     24     
     25 void add(int u,int v,int c,int w)
     26    {
     27      e[++cnt].to=v;
     28      e[cnt].next=head[u];    
     29         head[u]=cnt;
     30      e[cnt].c=c;
     31      e[cnt].w=w;
     32      e[cnt].from=u;     
     33      e[cnt].edge=c;
     34    }
     35    
     36 void insert(int u,int v,int c,int w)
     37    {
     38         add(u,v,c,w);
     39         add(v,u,0,-w);
     40     }
     41     
     42 bool bfs()
     43     {
     44       for (int i=1;i<=T;i++) dis[i]=INF;
     45       dis[S]=0;
     46       queue<int>que;
     47       que.push(S);
     48       while (!que.empty())    
     49         {
     50            int now=que.front();    
     51            que.pop();    
     52            for (int i=head[now];i;i=e[i].next)    
     53               if (e[i].edge&&dis[e[i].to]>dis[now]+1)
     54                  {
     55                       dis[e[i].to]=dis[now]+1;
     56                       que.push(e[i].to);
     57                       if (e[i].to==T) return 1;
     58                   }
     59         }
     60       return 0;    
     61      }
     62                 
     63 int dfs(int x,int inf)
     64      {
     65          if (x==T) return inf; 
     66          int rest=inf;
     67          for (int i=head[x];i&&rest;i=e[i].next)
     68             if (e[i].edge&&dis[e[i].to]==dis[x]+1)
     69                {
     70                    int now=dfs(e[i].to,min(e[i].edge,inf));
     71                    if (!now) dis[now]=0;
     72                    e[i].edge-=now;
     73                    e[i^1].edge+=now;
     74                    rest-=now;
     75                }
     76        return inf-rest;           
     77       } 
     78           
     79 bool spfa()
     80     {
     81        for (int i=1;i<=T;i++) dis[i]=INF;    
     82        queue<int>que;    
     83        que.push(S);
     84        inq[S]=1;
     85        dis[S]=0;
     86        while (!que.empty())
     87           {
     88                int now=que.front();
     89                que.pop();
     90                inq[now]=0;
     91                for (int i=head[now];i;i=e[i].next)
     92                   if (e[i].c&&dis[e[i].to]>dis[now]+e[i].w)
     93                    {
     94                       dis[e[i].to]=dis[now]+e[i].w;
     95                       from[e[i].to]=i;
     96                       if (!inq[e[i].to]) que.push((e[i].to)),inq[e[i].to]=1;
     97                    }
     98               }
     99        if (dis[T]!=INF) return 1;
    100            else return 0;              
    101     }
    102 
    103 void mcf()
    104    {
    105         int x=INF;
    106         for (int i=from[T];i;i=from[e[i].from])
    107            x=min(x,e[i].c); 
    108         for (int i=from[T];i;i=from[e[i].from])
    109         {
    110            ans+=e[i].w*x;
    111            e[i].c-=x;
    112            e[i^1].c+=x;    
    113             }               
    114      }
    115 void solve()
    116     {
    117       int ansn=0;
    118       while (bfs()) ansn+=dfs(S,INF);
    119       printf("%d ",ansn);
    120       while (spfa()) mcf();
    121       printf("%d
    ",ans);
    122     }
    123 
    124 int main()
    125     {
    126       scanf("%d%d",&n,&m);    
    127       insert(S,S+n,INF,0);
    128       for (int i=2;i<n;i++)
    129         insert(i,i+n,1,0);    
    130         insert(n,n<<1,INF,0);
    131       for (int i=1;i<=m;i++)     
    132           {
    133             int u,v,w;    
    134             scanf("%d%d%d",&u,&v,&w);
    135           insert(u+n,v,1,w);        
    136          }  
    137      solve();
    138      return 0;    
    139     }         
  • 相关阅读:
    EasyUI左边树菜单和datagrid分页
    Linux上安装Redis教程
    TreeMap和TreeSet的区别与联系
    将Map<String, List<Map<String,Object>>>进行排序
    Linux系统安装JDK和Tomcat
    点击添加按钮,使用ajax动态添加一行和移除一行,并且序号重新排序和数据不重复操作判断
    23种设计模式汇总整理
    SSH架构BaseDao实现
    双击Table表格td变成text修改内容
    用户找回密码功能JS验证邮箱通过点击下一步隐藏邮箱输入框并修改下一步按钮的ID
  • 原文地址:https://www.cnblogs.com/grhyxzc/p/5211118.html
Copyright © 2011-2022 走看看