zoukankan      html  css  js  c++  java
  • COJ 0501 取数游戏(TPM)

    取数游戏(TPM)
    难度级别:D; 运行时间限制:1000ms; 运行空间限制:51200KB; 代码长度限制:2000000B
    试题描述

    给你一个n*n的格子的棋盘,每个格子里面有一个非负数。从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能有公共边,并且取出的数的和最大。(二分图匹配练习)

    输入
    第一行是一个正整数n (n<20)。
    接下来是 n*n 个非负数。
    输出
    输出可能取得的最大的和。
    输入示例
    3
    5 9 4
    8 3 6
    2 7 1
    输出示例
    30
    其他说明
    n<20

    题解:“没有公共边”这是赤裸裸的二分图呀!随便按(i+j)&1造个二分图跑了就行。。。

    而且,这是我第一个接触的构造题吧= = 还是非常有纪念意义的= =我记得当年还是小健建给我亲自敲了一遍DInic然后敲了一遍这道题。。。回忆满满呢~

    现在老练的ISAP+缩行:

     1 //这两道题有什么区别。。。= =
     2 #include<iostream>   
     3 #include<cstdio>
     4 #include<cmath>
     5 #include<algorithm>
     6 #include<queue>
     7 #include<cstring>
     8 using namespace std;
     9 const int maxn=2002+10,maxm=80002+10,inf=-1u>>1;
    10 struct ISAP{
    11     struct tedge{int x,y,w,next;}adj[maxm];int ms,fch[maxn];
    12     int d[maxn],s[maxn],cur[maxn],gap[maxn],n,top;
    13     void init(int n){
    14         this->n=n;ms=0;top=0;
    15         memset(d,-1,sizeof(d));
    16         memset(fch,-1,sizeof(fch));
    17         return;
    18     }
    19     void addedge(int u,int v,int w){
    20         adj[ms]=(tedge){u,v,w,fch[u]};fch[u]=ms++;
    21         adj[ms]=(tedge){v,u,0,fch[v]};fch[v]=ms++;
    22         return;
    23     }
    24     void bfs(){
    25         queue<int>Q;Q.push(n);d[n]=0;
    26         while(!Q.empty()){
    27             int u=Q.front();Q.pop();
    28             for(int i=fch[u];i!=-1;i=adj[i].next){
    29                 int v=adj[i].y;
    30                 if(d[v]==-1) d[v]=d[u]+1,Q.push(v);
    31             }
    32         } return;
    33     }
    34     int maxflow(int S,int T){
    35         n=T;bfs();int k=S,i,flow=0;
    36         for(i=0;i<=n;i++) cur[i]=fch[i],gap[d[i]]++;
    37         while(d[S]<n){
    38             if(k==n){
    39                 int mi=inf,pos;
    40                 for(i=0;i<top;i++) if(adj[s[i]].w<mi) mi=adj[s[i]].w,pos=i;
    41                 for(i=0;i<top;i++) adj[s[i]].w-=mi,adj[s[i]^1].w+=mi;
    42                 flow+=mi;top=pos;k=adj[s[top]].x;
    43             }
    44             for(i=cur[k];i!=-1;i=adj[i].next){
    45                 int v=adj[i].y;
    46                 if(adj[i].w&&d[k]==d[v]+1){cur[k]=i;k=v;s[top++]=i;break;}
    47             }
    48             if(i==-1){
    49                 int lim=n;
    50                 for(i=fch[k];i!=-1;i=adj[i].next){
    51                     int v=adj[i].y;
    52                     if(adj[i].w&&d[v]<lim) lim=d[v],cur[k]=i;
    53                 } if(--gap[d[k]]==0) break;
    54                 d[k]=lim+1;gap[d[k]]++;
    55                 if(k!=S) k=adj[s[--top]].x;
    56             }
    57         } return flow;
    58     }
    59 }sol;
    60 inline int read(){
    61     int x=0,sig=1;char ch=getchar();
    62     while(!isdigit(ch)){if(ch=='-') sig=-1;ch=getchar();}
    63     while(isdigit(ch)) x=10*x+ch-'0',ch=getchar();
    64     return x*=sig;
    65 }
    66 inline void write(int x){
    67     if(x==0){putchar('0');return;}if(x<0) putchar('-'),x=-x;
    68     int len=0,buf[15];while(x) buf[len++]=x%10,x/=10;
    69     for(int i=len-1;i>=0;i--) putchar(buf[i]+'0');return;
    70 }
    71 int A[21][21],mx[]={1,-1,0,0},my[]={0,0,-1,1};
    72 void init(){
    73     int n=read();long long ans=0;
    74     sol.init(n*n+2);int S=n*n+1,T=n*n+2;
    75     for(int i=1;i<=n;i++)
    76        for(int j=1;j<=n;j++){
    77                A[i][j]=read();
    78             if((i+j)&1){
    79                sol.addedge(S,i*n+j-n,A[i][j]);
    80                for(int d=0;d<4;d++){
    81                    int nx=i+mx[d],ny=j+my[d];
    82                    if(nx>=1&&nx<=n&&ny>=1&&ny<=n) sol.addedge(i*n+j-n,nx*n+ny-n,inf);
    83                }
    84            }
    85            else sol.addedge(i*n+j-n,T,A[i][j]);
    86            ans+=A[i][j];
    87        } 
    88     write(ans-sol.maxflow(S,T));
    89     return;
    90 }
    91 void work(){
    92     return;
    93 }
    94 void print(){
    95     return;
    96 }
    97 int main(){
    98     init();work();print();return 0;
    99 }

    当时最稚嫩的代码。。。真的有种说不出的感动:

      1 #include <iostream>
      2 #include <queue>
      3 using namespace std;
      4 
      5 const int maxn = 400 + 10;
      6 const int maxm = 10000 + 10;
      7 
      8 struct Edge
      9 {
     10     int from, to, cap, flow;
     11 };
     12 
     13 struct Dinic
     14 {
     15     int n, m, s, t;
     16     int first[maxn], next[maxm];
     17     
     18     Edge edges[maxm];
     19     
     20     void init(int n)
     21     {
     22         this -> n = n;
     23         m = 0;
     24         
     25         memset(first, -1, sizeof(first));
     26         
     27         return ;
     28     }
     29     
     30     void AddEdge(int from, int to, int cap)
     31     {
     32         edges[m] = (Edge){from, to, cap, 0};
     33         next[m] = first[from];
     34         first[from] = m++;
     35         
     36         edges[m] = (Edge){to, from, 0, 0};
     37         next[m] = first[to];
     38         first[to] = m++;
     39         
     40         return ;
     41     }
     42     
     43     int d[maxn], cur[maxn];
     44     bool vis[maxn];
     45     
     46     int BFS()
     47     {
     48         memset(vis, 0, sizeof(vis));
     49         queue<int> Q;
     50         
     51         Q.push(s);
     52         vis[s] = true;
     53         d[s] = 0;
     54         
     55         
     56         
     57         while(!Q.empty())
     58         {
     59             int x = Q.front(); Q.pop();
     60             
     61             for(int i = first[x]; i != -1; i = next[i])
     62             {
     63                 Edge& e = edges[i];
     64                 if(!vis[e.to] && e.cap > e.flow)
     65                 {
     66                     vis[e.to] = true;
     67                     d[e.to] = d[x] + 1;
     68                     Q.push(e.to);
     69                 }
     70             }
     71         }
     72             
     73         return vis[t];
     74     }
     75     int DFS(int x, int a)
     76     {
     77         if(x == t || !a) return a;
     78         
     79         int f, flow = 0;
     80         
     81         for(int& i = cur[x]; i != -1; i = next[i])
     82         {
     83             Edge& e = edges[i];
     84             if(d[e.to] == d[x] + 1 && (f = DFS(e.to, min(a, e.cap - e.flow))) > 0)
     85             {
     86                 flow += f;
     87                 a -= f;
     88                 e.flow += f;
     89                 edges[i ^ 1].flow -= f;
     90                 if(!a) break;
     91             }
     92         }
     93         return flow;
     94     }
     95     
     96     
     97     int MaxFlow(int s, int t)
     98     {
     99         this -> s = s;
    100         this -> t = t;
    101         
    102         int flow = 0;
    103         
    104         while(BFS())
    105         {
    106             for(int i = 0; i < n; i++) cur[i] = first[i];
    107             flow += DFS(s, 1000000000);
    108         }
    109         return flow;   //你大爷!!!!!!!!!!!!!!!! 
    110     }
    111 }sol;
    112 
    113 int a[21][21];
    114 int nx[] = {0, 0, -1, 1};
    115 int ny[] = {-1, 1, 0, 0};
    116 
    117 int main()
    118 {
    119     int n, m;
    120     scanf("%d", &n);
    121     
    122     m = n;
    123     
    124     sol.init(n * m + 2);
    125     
    126     long long double tot = 0;
    127     
    128     int s = n * m;
    129     int t = n * m + 1;
    130     
    131     for(int i = 0; i < n; i++)
    132       for(int j = 0; j < m; j++)
    133       {
    134           scanf("%d", &a[i][j]);
    135           tot += a[i][j];
    136           if((i + j) & 1)
    137           {
    138               sol.AddEdge(s, i * m + j, a[i][j]);
    139               
    140               
    141               for(int d = 0; d < 4; d++)
    142               {
    143                   int mx = nx[d] + i;
    144                   int my = ny[d] + j;
    145                   
    146                   if(mx >= 0 && mx < n && my >= 0 && my < m)
    147                   {
    148                       sol.AddEdge(i * m + j, mx * m + my, 2000000000);
    149                   }
    150               }
    151           }
    152           else sol.AddEdge(i * m + j, t, a[i][j]);
    153       }
    154       
    155     printf("%d
    ", tot - sol.MaxFlow(s, t)); 156     
    157     //system("pause");
    158     return 0;
    159 }
  • 相关阅读:
    Java3D实例应用载入VRML模型
    Tomcat数据库连接池的配置方法总结
    WebGL学习笔记使用3D引擎threeJS实现星空粒子移动
    mybatis应用实例学习
    springmvc 实例应用
    springmvc定制伪REST风格及JSR303Bean校验整合
    SpringMVC中应用Ajax异步通讯
    Java3D实例应用载入3ds 模型
    Device Mutipath参数设置
    Nginx+FastCGI+Python
  • 原文地址:https://www.cnblogs.com/chxer/p/4542665.html
Copyright © 2011-2022 走看看