zoukankan      html  css  js  c++  java
  • 传纸条

    这个建图也是很妙

    原题:
    小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题。一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了。幸运的是,他们可以通过传纸条来进行交流。纸条要经由许多同学传到对方手里,小渊坐在矩阵的左上角,坐标(1,1),小轩坐在矩阵的右下角,坐标(m,n)。从小渊传到小轩的纸条只可以向下或者向右传递,从小轩传给小渊的纸条只可以向上或者向左传递。 

    在活动进行中,小渊希望给小轩传递一张纸条,同时希望小轩给他回复。班里每个同学都可以帮他们传递,但只会帮他们一次,也就是说如果此人在小渊递给小轩纸条的时候帮忙,那么在小轩递给小渊的时候就不会再帮忙。反之亦然。 

    还有一件事情需要注意,全班每个同学愿意帮忙的好感度有高有低(注意:小渊和小轩的好心程度没有定义,输入时用0表示),可以用一个0-100的自然数来表示,数越大表示越好心。小渊和小轩希望尽可能找好心程度高的同学来帮忙传纸条,即找到来回两条传递路径,使得这两条路径上同学的好心程度只和最大。现在,请你帮助小渊和小轩找到这样的两条路径。

    1<=m,n<=50

    明明两个dfs就可以A掉的题非要用费用流写系列

    用费用流的话建图是个很大的问题,我考虑过建两个图或者跑两边,酱紫就不能满足只能经过一次的限制了,又想过把源和汇连起来,酱紫就不能限制去的时候和回来的时候走的方向限制了

    然后看了山神的题解,只能说妙啊

    为啥非要跑回来呢,题目本质是求两条不相交的路,在建图的时候给源和汇连的边流量为2不就行了

    网络流妙啊

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 int read(){int z=0,mark=1;  char ch=getchar();
     8     while(ch<'0'||ch>'9'){if(ch=='-')mark=-1;  ch=getchar();}
     9     while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0';  ch=getchar();}
    10     return z*mark;
    11 }
    12 const int oo=168430090;
    13 struct ddd{int next,y,evalue,rev,cost;}e[1100000];  int LINK[510000],ltop=0;
    14 inline void insert(int x,int y,int z,int _cost){
    15     e[++ltop].next=LINK[x];LINK[x]=ltop;e[ltop].y=y;e[ltop].evalue=z;e[ltop].rev=ltop+1;e[ltop].cost=_cost;
    16     e[++ltop].next=LINK[y];LINK[y]=ltop;e[ltop].y=x;e[ltop].evalue=0;e[ltop].rev=ltop-1;e[ltop].cost=-_cost;
    17 }
    18 int n,m,a[110][110];  int s,t;  int S;
    19 int QUEUE[510000],head=0;  bool visited[510000];
    20 int last[510000],last_e[510000];
    21 int dist[510000];
    22 inline int get_id(int x,int y){return (x-1)*n+y-1;}
    23 bool spfa(){
    24     memset(visited,0,sizeof(visited));
    25     memset(dist,-1,sizeof(dist));
    26     QUEUE[head=1]=s;  visited[s]=true;  dist[s]=0;
    27     for(int k=1;k<=head;k++){
    28         for(int i=LINK[QUEUE[k]];i;i=e[i].next)
    29             if(e[i].evalue && dist[QUEUE[k]]+e[i].cost>dist[e[i].y]){
    30                 dist[e[i].y]=dist[QUEUE[k]]+e[i].cost;
    31                 last[e[i].y]=QUEUE[k],last_e[e[i].y]=i;
    32                 if(!visited[e[i].y]){  QUEUE[++head]=e[i].y;  visited[e[i].y]=true;}
    33             }
    34         visited[QUEUE[k]]=false;
    35     }
    36     return dist[t]!=-1;
    37 }
    38 int cost_flow(){
    39     int bowl=0;
    40     while(spfa()){
    41         int min_flow=oo;
    42         for(int i=t;i!=s;i=last[i])  min_flow=min(min_flow,e[last_e[i]].evalue);
    43         for(int i=t;i!=s;i=last[i]){
    44             bowl+=e[last_e[i]].cost;
    45             e[last_e[i]].evalue-=min_flow,e[e[last_e[i]].rev].evalue+=min_flow;
    46         }
    47     }
    48     return bowl;
    49 }
    50 int main(){//freopen("ddd.in","r",stdin);
    51     cin>>m>>n;  s=0,S=m*n;  t=S*2+1;
    52     for(int i=1;i<=m;i++)for(int j=1;j<=n;j++)a[i][j]=read();
    53     for(int i=1;i<=m;i++)for(int j=1;j<=n;j++){
    54         int _id=get_id(i,j);
    55         if((i==1 && j==1)||(i==m && j==n))  insert(_id,_id+S,2,0);
    56         else  insert(_id,_id+S,1,a[i][j]);
    57         if(j!=n)  insert(_id+S,get_id(i,j+1),oo,0);
    58         if(i!=m)  insert(_id+S,get_id(i+1,j),oo,0);
    59     }
    60     insert(s,get_id(1,1),2,0),insert(get_id(m,n)+S,t,2,0);
    61     cout<<cost_flow()<<endl;
    62     return 0;
    63 }
    View Code
  • 相关阅读:
    mysql 数据迁移方案
    tomcat:run 指定端口号
    idea open gradle project
    tomcat:run命令执行端口号
    域名代理
    stackoverflow慢问题
    chrome 添加 vue tools
    深度学习——结构化机器学习项目(学习策略2)[9]
    深度学习——超参数调试[7]
    深度学习——优化算法[6]
  • 原文地址:https://www.cnblogs.com/JSL2018/p/6297428.html
Copyright © 2011-2022 走看看