• Gym


    Gym - 102346G Getting Confidence

    题意:n*n的格子,每个格子上有一个数,要求每行每列都只能拿一个数,使得乘积最大,然后输出每列选择的是第几行的数。

    如果是加法的话,那么很明显,就是一个网络流。可是,现在是乘法怎么办,很简单,直接取log,那么乘法便转换成了加法,然后就可以建图。

    每行每列只能取一个数,就相当于行列是拆开的点,因为需要输出的是列的信息,那么源点向每一列建一条流量为1,费用为0的边,而每一行向汇点建一条流量为1,费用为0的边。

    再对于每个格子,每一列向它这一列的格子建一条流量为1,费用为0的点,而每个格子向它所在的行建一条流量为1,费用为-log(格子上的数)的边。

    最后跑一遍最小费用最大流,看一下每一列的那条边流量为0

     1 #include<cstdio>
     2 #include<cmath>
     3 #include<queue> 
     4 #include<algorithm>
     5 using namespace std;
     6 const int N=2e4+11,M=1e6+11,inf=1e9+7;
     7 struct Side{
     8     int v,ne,w;
     9     double val;
    10 }S[M<<1];
    11 double dis[N];
    12 int n,sn,sb,se,head[N],vis[N],flow[N],lu[N];
    13 void init(){
    14     sn=0;
    15     sb=0;se=n*n+2*n+1;
    16     for(int i=sb;i<=se;i++) head[i]=-1;
    17 }
    18 void add(int u,int v,int w,double val){
    19     S[sn].w=w;S[sn].val=val;
    20     S[sn].v=v;S[sn].ne=head[u];
    21     head[u]=sn++;
    22 }
    23 void addE(int u,int v,int w,double val){
    24     add(u,v,w,val);add(v,u,0,-val); 
    25 }
    26 bool spfa(){
    27     queue<int> q;
    28     for(int i=sb;i<=se;i++){
    29         dis[i]=inf;
    30         vis[i]=0;
    31         flow[i]=inf;
    32         lu[i]=-1;
    33     }
    34     dis[sb]=0;
    35     vis[sb]=1;
    36     q.push(sb);
    37     int u,v;
    38     while(!q.empty()){
    39         u=q.front();q.pop();vis[u]=0;
    40         for(int i=head[u];~i;i=S[i].ne){
    41             v=S[i].v;
    42             if(S[i].w>0&&dis[v]>dis[u]+S[i].val){
    43                 lu[v]=i;
    44                 dis[v]=dis[u]+S[i].val;
    45                 flow[v]=min(flow[u],S[i].w);
    46                 if(!vis[v]){
    47                     vis[v]=1;
    48                     q.push(v);
    49                 }
    50             }
    51         }
    52     }
    53     return dis[se]!=inf; 
    54 }
    55 void mfml(){
    56     int ans=0,ansc=0;
    57     while(spfa()){
    58         ans+=flow[se];
    59         ansc+=flow[se]*dis[se];
    60         for(int i=lu[se];~i;i=lu[S[i^1].v]){
    61             S[i].w-=flow[se];
    62             S[i^1].w+=flow[se];
    63         }
    64     }
    65 }
    66 int main(){
    67     while(~scanf("%d",&n)){
    68         init();;
    69         for(int i=1;i<=n;i++){
    70             addE(sb,n*n+n+i,1,0.0);
    71             addE(n*n+i,se,1,0.0);
    72         }
    73         for(int i=1,x;i<=n;i++){
    74             for(int j=1;j<=n;j++){
    75                 scanf("%d",&x);
    76                 addE(n*n+n+j,(i-1)*n+j,1,0.0);
    77                 addE((i-1)*n+j,n*n+i,1,-log(1.0*x));
    78             }
    79         }
    80         mfml();
    81         for(int i=1;i<=n;i++)
    82             for(int j=head[n*n+n+i];~j;j=S[j].ne){
    83                 if(S[j].w||S[j].v==sb) continue;
    84                 printf("%d%c",(S[j].v-1)/n+1," 
    "[i==n]);
    85                 break;
    86             }
    87     }
    88     return 0;
    89 } 
    log转乘为加
  • 相关阅读:
    为啥负利率国债有人抢着买?因为时代变了
    微增长时代
    U盘插入电脑后图标是灰色的,打开提示“请将磁盘插入驱动器”
    计算shell 脚本的执行时间
    win10系统应用商店打开后无法联网 代码: 0x80131500 的解决办法
    Jetbrains家的软件都可用的激活码-pycharm
    postman中x-www-form-urlencoded与form-data的区别
    升级Gogs版本
    上海对售价超1499元的茅台酒即没收并另处罚款
    提高收入的根本途径
  • 原文地址:https://www.cnblogs.com/LMCC1108/p/11719041.html
Copyright © 2020-2023  润新知