• 【费用流】BZOJ1877[SDOI2009]-晨跑


    【题目大意】

    Elaxia每天从寝室出发跑到学校,保证寝室编号为1,学校编号为N。 Elaxia的晨跑计划是按周期(包含若干天)进行的,由于他不喜欢走重复的路线,所以在一个周期内,每天的晨跑路线都不会相交(在十字路口处),寝室和学校不算十字路口。表示路口a和路口b之间有条长度为c的街道(单向),求出最长周期的天数和满足最长天数的条件下最短的路程长度。

    【思路】

    拆点。我们可以将每个路口拆成两个点(i)和(i+N)。由于Ai与Bi之间有长度为C的街道,则在(Ai)和(Bi+N)之间添加一条容量为1,费用为c的边。然后对于每个Ai,添加一条(Ai+n,Ai)的边,容量为1(保证每个路口仅仅经过一次),费用为0的边。最大流即可。

    要注意的是1和N不算是路口,所以(1与n+1)(n与2n)之间的边容量为INF。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<cmath>
      6 #include<queue>
      7 #include<vector>
      8 using namespace std;
      9 const int MAXm=20000+50;
     10 const int MAXn=(200+50)*2;
     11 const int INF=0x7fffffff;
     12 int n,m;//十字路口数和街道数 
     13 struct node
     14 {
     15     int to,cap,cost,pos;    
     16 };
     17 vector<node> E[MAXn];
     18 int pre[MAXn],preedge[MAXn];
     19 
     20 void addedge(int u,int v,int cap,int cost)
     21 {
     22     E[u].push_back((node){v,cap,cost,E[v].size()});
     23     E[v].push_back((node){u,0,-cost,E[u].size()-1});
     24 }
     25 
     26 void init()
     27 {
     28     scanf("%d%d",&n,&m);
     29     for (int i=0;i<m;i++)
     30     {
     31         int u,v,cost;
     32         scanf("%d%d%d",&u,&v,&cost);
     33         addedge(u,n+v,1,cost); 
     34     }
     35     for (int i=2;i<=n-1;i++) addedge(n+i,i,1,0);
     36     addedge(n+1,1,INF,0);
     37     addedge(2*n,n,INF,0);
     38     //建图的时候不要忘掉了,从1和n+1的边,n和2n的边容量为INF,否则只能跑一天! 
     39 }
     40 
     41 int SPFA()
     42 {
     43     int dis[MAXn],vis[MAXn];
     44     for (int i=1;i<=2*n;i++) dis[i]=INF;
     45     memset(vis,0,sizeof(vis));
     46     memset(pre,-1,sizeof(pre));
     47     queue<int>que;
     48     que.push(1);
     49     dis[1]=0; 
     50     vis[1]=1;
     51     while (!que.empty())
     52     {
     53         int head=que.front();
     54         que.pop();
     55         vis[head]=0;
     56         for (int i=0;i<E[head].size();i++)
     57         {
     58             node& tmp=E[head][i]; 
     59             if (tmp.cap>0 && dis[tmp.to]>dis[head]+tmp.cost)
     60             {
     61                 dis[tmp.to]=dis[head]+tmp.cost;
     62                 pre[tmp.to]=head;
     63                 preedge[tmp.to]=i;
     64                 if (!vis[tmp.to])
     65                 {
     66                     vis[tmp.to]=1;
     67                     que.push(tmp.to);
     68                 }
     69             }
     70         }
     71     }
     72     if (dis[n]==INF) return 0;//这里是返回到n而不是2n 
     73     else return 1;
     74 }
     75 
     76 void mcmf()
     77 {
     78     int ans=0,days=0;
     79     while (SPFA())
     80     {
     81         days++; 
     82         int flow=INF;
     83         for (int i=n;pre[i]!=-1;i=pre[i])
     84             flow=min(flow,E[pre[i]][preedge[i]].cap);
     85         for (int i=n;pre[i]!=-1;i=pre[i])
     86         {
     87             node& tmp=E[pre[i]][preedge[i]];
     88             tmp.cap-=flow;
     89             E[tmp.to][tmp.pos].cap+=flow;
     90             ans+=flow*tmp.cost;
     91         }
     92     }
     93     cout<<days<<' '<<ans<<endl;
     94 }
     95 
     96 int main()
     97 {
     98     init();
     99     mcmf();
    100     return 0;
    101 }
  • 相关阅读:
    geoserver 地图性能和缓存
    geoserver PostGIS的安装和使用
    geoserver 数据图层输出格式
    Centos7Yum安装配置指定版本nginx
    Centos7Yum安装PHP7.2
    CentOS7 中把默认yum源更换成163源
    安装配置Elasticserch的方法
    redis的持久化(RDB&AOF的区别)
    LayerDate渲染多个class出现闪现问题的解决
    explain分析SQL语句详解
  • 原文地址:https://www.cnblogs.com/iiyiyi/p/5246596.html
Copyright © 2020-2023  润新知