zoukankan      html  css  js  c++  java
  • [SCOI2012]奇怪的游戏 (网络流)

    Description

    Blinker最近喜欢上一个奇怪的游戏。 
    这个游戏在一个 N*M 的棋盘上玩,每个格子有一个数。每次 Blinker 会选择两个相邻
    的格子,并使这两个数都加上 1。 
    现在 Blinker 想知道最少多少次能使棋盘上的数都变成同一个数,如果永远不能变成同
    一个数则输出-1。 

    Input

    输入的第一行是一个整数T,表示输入数据有T轮游戏组成。 
    每轮游戏的第一行有两个整数N和M, 分别代表棋盘的行数和列数。 
    接下来有N行,每行 M个数。 

    Output


      对于每个游戏输出最少能使游戏结束的次数,如果永远不能变成同一个数则输出-1。

    Sample Input

    2
    2 2
    1 2
    2 3
    3 3
    1 2 3
    2 3 4
    4 3 2

    Sample Output

    2
    -1

    HINT

    【数据范围】 

        对于30%的数据,保证  T<=10,1<=N,M<=8 

    对于100%的数据,保证  T<=10,1<=N,M<=40,所有数为正整数且小于1000000000 

     
    题解大家去hzwer里看吧 说的很好  http://hzwer.com/5992.html
    这只留一个代码
     
      1 #include<queue>
      2 #include<cstdio> 
      3 #include<cstring>
      4 #include<iostream>
      5 #define MAXN 1010
      6 #define LL long long
      7 
      8 using namespace std;
      9 
     10 const LL INF=(1LL<<50);
     11 
     12 struct Quix {
     13     int to;
     14     int next;
     15     LL val;
     16 };
     17 Quix e[20010];
     18 
     19 int head[MAXN<<1],cur[MAXN<<1],tot=1;
     20 
     21 int T,n,m,src,decc,n1,n2,mx=-1;
     22 
     23 LL s1,s2;  //血的教训 忘了long long 
     24 
     25 int depth[MAXN<<1],a[50][50],color[50][50];
     26 
     27 int X[4]={0,1,-1,0};
     28 int Y[4]={1,0,0,-1};  //上下左右我竟然少搜了一个方向 
     29 
     30 queue<int> Q;
     31 
     32 inline void read(int&x) {
     33     int f=1;x=0;char c=getchar();
     34     while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
     35     while(c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-48;c=getchar();}
     36     x=x*f;
     37 }
     38 
     39 inline void add(int x,int y,LL z) {
     40     e[++tot].to=y;
     41     e[tot].val=z;
     42     e[tot].next=head[x];
     43     head[x]=tot;
     44 }
     45 
     46 inline void add_edge(int x,int y,LL z) {
     47     add(x,y,z);
     48     add(y,x,0);
     49 }
     50 
     51 inline int cal(int i,int j) {
     52     return (i-1)*m+j;
     53 }
     54 
     55 bool bfs() {
     56     for(int i=0;i<=decc;i++) cur[i]=head[i],depth[i]=-1;
     57     while(!Q.empty()) Q.pop();
     58     Q.push(src);
     59     depth[src]=0;
     60     while(!Q.empty()) {
     61         int u=Q.front();
     62         Q.pop();
     63         for(int i=head[u];i!=-1;i=e[i].next) {
     64             int to=e[i].to;
     65             if(e[i].val&&depth[to]==-1) {
     66                 Q.push(to);
     67                 depth[to]=depth[u]+1;
     68                 if(to==decc) return true;
     69             }
     70         }
     71     }
     72     return false;
     73 }
     74 
     75 LL dfs(int now,LL flow) {
     76     if(now==decc) return flow;
     77     LL used=0,delat;
     78     for(int & i=cur[now];i!=-1;i=e[i].next) {
     79         int to=e[i].to;
     80         if(e[i].val&&depth[to]==depth[now]+1) {
     81             delat=flow-used;
     82             delat=dfs(to,min(e[i].val,delat));
     83             e[i].val-=delat;
     84             e[i^1].val+=delat;
     85             used+=delat;
     86             if(used==flow) break;
     87         }
     88     }
     89     if(!used) depth[now]=-1;
     90     return used;
     91 }
     92 
     93 inline LL dinic() {
     94     LL ans=0;
     95     while(bfs()) 
     96       ans+=dfs(src,INF);
     97     return ans;
     98 }
     99 
    100 inline bool check(LL x) {
    101     LL cnt=0;
    102     tot=1;
    103     memset(head,-1,sizeof head);
    104     for(int i=1;i<=n;i++)
    105       for(int j=1;j<=m;j++)
    106         if(color[i][j]) {
    107             add_edge(src,cal(i,j),x-a[i][j]);
    108             cnt+=x-a[i][j];
    109             for(int k=0;k<4;k++) {
    110                 int nx=i+X[k];
    111                 int ny=j+Y[k];
    112                 if(nx<1||nx>n||ny<1||ny>m) continue;
    113                 add_edge(cal(i,j),cal(nx,ny),INF);
    114             }
    115         }
    116         else add_edge(cal(i,j),decc,x-a[i][j]);
    117     if(dinic()==cnt) return true;
    118     return false;
    119 }
    120 
    121 inline int hhh() {
    122     read(T);
    123     while(T--) {
    124         mx=-1;
    125         n1=n2=s1=s2=0;
    126         read(n);read(m);
    127         src=0;decc=n*m+1;
    128         for(int i=1;i<=n;i++)
    129           for(int j=1;j<=m;j++) {
    130               read(a[i][j]);
    131               color[i][j]=(i+j)&1;
    132               mx=max(mx,a[i][j]);
    133             if(color[i][j]) s1+=(LL)a[i][j],n1++;
    134               else s2+=(LL)a[i][j],n2++;
    135           }
    136         if(n1!=n2) {
    137             LL x=(s2-s1)/(n2-n1);
    138             if(x>=mx) 
    139               if(check(x)) {
    140                   printf("%lld
    ",(LL)x*n1-s1);
    141                   continue;
    142               }
    143             printf("-1
    ");
    144         }
    145         else {
    146             if(s1!=s2) {
    147                 printf("-1
    ");
    148                 continue;
    149             }
    150             LL l=mx,r=INF;
    151             while(l<=r) {
    152                 LL mid=(l+r)>>1;
    153                 if(check(mid)) r=mid-1;
    154                 else l=mid+1;
    155             }
    156             printf("%lld
    ",(LL)l*n1-s1);
    157         }
    158     }    
    159     return 0;
    160 }
    161 
    162 int sb=hhh();
    163 int main() {;}
    代码


    作者:乌鸦坐飞机
    出处:http://www.cnblogs.com/whistle13326/
    新的风暴已经出现 怎么能够停止不前 穿越时空 竭尽全力 我会来到你身边 微笑面对危险 梦想成真不会遥远 鼓起勇气 坚定向前 奇迹一定会出现

     
  • 相关阅读:
    关于删除表记录 与 清空表记录
    alter table,复制, 单表查询
    表之间的关系
    表的约束条件
    表的数据类型
    创建表的完整语法
    MYSQL基本语句
    MYSQL安装及环境搭建
    支付宝二次封装、订单模块与表分析、订单模块接口分析、支付接口、重写序列化类的create方法、前后台回调接口配置、前台生成订单并跳转、前台支付成功页面、支付宝get回调参数、同步异步回调接口、上线前准备
    区间过滤、课程主页前端、课程详情页前端、课程单查接口、章节分类接口、七牛云视频托管、后台搜索接口、前台搜索页面完成、沙箱环境
  • 原文地址:https://www.cnblogs.com/whistle13326/p/7327886.html
Copyright © 2011-2022 走看看