zoukankan      html  css  js  c++  java
  • 洛谷P3159 [CQOI2012]交换棋子

    巧妙的拆点方式,首先把1看成黑点,0看成空的,几次交换就可以看成一条路径

    1)从容量上看,这条路径为1-2-2-2-2-2-……-2-1

    2)从费用上看,这条路径每条边费用都是1

    于是用一种巧妙的拆点方式,把一个点拆成三个,连两条边,成为一条链,

    然后如果是黑点的话就由s向中间那个点连边,如果是路过的话就由一条链的尾部向另一条链的首部连边

    这样就满足了上面的条件1)2)

    容量的话如果是黑点出来就是(c+1)/2,进来是c/2,其他的以此类推

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<vector>
      6 #include<queue>
      7 #define rint register int
      8 #define ll long long
      9 #define MAXN 2000+10
     10 #define pb push_back
     11 #define INF 0x7f7f7f7f
     12 #define oo 0x7f7f7f7f7f7f7f7f
     13 #define pil pair<int,ll>
     14 #define mp make_pair
     15 using namespace std;
     16 int read(){
     17     int x=0,f=1;char ch=getchar();
     18     while(ch<'0'||ch>'9'){if('-'==ch)f=-1;ch=getchar();}
     19     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     20     return x*f;
     21 }
     22 struct E{
     23     int from,to,cap,flow;
     24     ll cost;
     25     E(int x=0,int y=0,int c=0,int f=0,ll w=0LL){
     26         from=x,to=y,cap=c,flow=f,cost=w;
     27     }
     28 };
     29 struct Dinic{
     30     int n,m,s,t;
     31     vector<E> es;
     32     vector<int> G[MAXN];
     33     void init(int n,int s,int t){
     34         this->n=n;
     35         this->s=s,this->t=t;
     36         es.clear();
     37         for(int i=0;i<=n;i++)G[i].clear();
     38     }
     39     void add(int x,int y,int cap,ll cost){
     40         es.pb(E(x,y,cap,0,cost));
     41         es.pb(E(y,x,0,0,-cost));
     42         m=es.size();
     43         G[x].pb(m-2),G[y].pb(m-1);
     44     }
     45     int p[MAXN],a[MAXN];
     46     ll d[MAXN];
     47     int b[MAXN];
     48     bool SPFA(int &flow,ll &cost){
     49         p[s]=0,a[s]=INF;
     50         memset(d,0x7f,sizeof(d));
     51         d[s]=0;
     52         memset(b,0,sizeof(b));
     53         b[s]=1;
     54         queue<int> q;
     55         q.push(s);
     56         while(!q.empty()){
     57             int x=q.front();q.pop();b[x]=0;
     58             for(rint i=0;i<G[x].size();i++){
     59                 E &e=es[G[x][i]];
     60                 if(e.cap>e.flow&&d[e.to]>d[x]+e.cost){
     61                     p[e.to]=G[x][i];
     62                     a[e.to]=min(a[x],e.cap-e.flow);
     63                     d[e.to]=d[x]+e.cost;
     64                     if(!b[e.to]){
     65                         b[e.to]=1;
     66                         q.push(e.to);
     67                     }
     68                 }
     69             }
     70         }
     71         if(oo==d[t]){
     72             return 0;
     73         }
     74         flow+=a[t];
     75         cost+=a[t]*d[t];
     76         for(rint i=t;i!=s;i=es[p[i]].from){
     77             es[p[i]].flow+=a[t];
     78             es[p[i]^1].flow-=a[t];
     79         }
     80         return 1;
     81     }
     82     pil MaxfMinc(){
     83         int flow=0;
     84         ll cost=0LL;
     85         while(SPFA(flow,cost));
     86         return mp(flow,cost);
     87     }
     88 }D;
     89 int n,m,s=0,t=MAXN-1;
     90 int id[3][25][25];
     91 int a[25][25],b[25][25],p[25][25];
     92 int cnt1=0,cnt2=0;
     93 void init(){
     94     n=read();m=read();
     95     D.init(t,s,t);
     96     char c[25];
     97     for(rint i=1;i<=n;i++){
     98         for(rint j=1;j<=m;j++){
     99             id[0][i][j]=(i-1)*m+j;
    100         }
    101     }
    102     for(rint k=1;k<=2;k++){
    103         for(rint i=1;i<=n;i++){
    104             for(rint j=1;j<=m;j++){
    105                 id[k][i][j]=id[k-1][i][j]+n*m;
    106             }
    107         }
    108     }
    109     for(rint i=1;i<=n;i++){
    110         scanf("%s",c+1);
    111         for(rint j=1;j<=m;j++){
    112             a[i][j]=c[j]-'0';
    113         }
    114     }
    115     for(rint i=1;i<=n;i++){
    116         scanf("%s",c+1);
    117         for(rint j=1;j<=m;j++){
    118             b[i][j]=c[j]-'0';
    119         }
    120     }
    121     for(rint i=1;i<=n;i++){
    122         for(rint j=1;j<=m;j++){
    123             if(a[i][j]&&b[i][j]){
    124                 a[i][j]=b[i][j]=0;
    125             }    
    126             else if(a[i][j]){
    127                 cnt1++;
    128             }
    129             else if(b[i][j]){
    130                 cnt2++;
    131             }
    132         }
    133     }
    134     for(rint i=1;i<=n;i++){
    135         scanf("%s",c+1);
    136         for(rint j=1;j<=m;j++){
    137             p[i][j]=c[j]-'0';
    138         }
    139     }
    140 }
    141 void add(int x,int y,int c1,int c2){
    142     D.add(id[0][x][y],id[1][x][y],c1,0);
    143     D.add(id[1][x][y],id[2][x][y],c2,0);
    144 }
    145 void solve(){
    146     int dx[8]={0,0,-1,1,-1,-1,1,1};
    147     int dy[8]={1,-1,0,0,-1,1,-1,1};
    148     for(rint i=1;i<=n;i++){
    149         for(rint j=1;j<=m;j++){
    150             if(a[i][j]){
    151                 add(i,j,p[i][j]>>1,(p[i][j]+1)>>1);
    152                 D.add(s,id[1][i][j],1,0);
    153             }
    154             else if(b[i][j]){
    155                 add(i,j,(p[i][j]+1)>>1,p[i][j]>>1);
    156                 D.add(id[1][i][j],t,1,0);
    157             }
    158             else{
    159                 add(i,j,(p[i][j]+1)>>1,p[i][j]>>1);                
    160             }
    161             for(rint k=0;k<8;k++){
    162                 int x=i+dx[k],y=j+dy[k];
    163                 if(1<=x&&x<=n&&1<=y&&y<=m){
    164                     D.add(id[2][i][j],id[0][x][y],INF,1);
    165                 }
    166             }
    167         }
    168     }
    169     pil ans=D.MaxfMinc();
    170     if(ans.first!=cnt1||cnt1!=cnt2){
    171         printf("-1
    ");
    172     }
    173     else{
    174         printf("%d
    ",ans.second);
    175     }
    176 }
    177 int main()
    178 {
    179     init();
    180     solve();
    181     return 0;
    182 }
  • 相关阅读:
    Makefile的常用技术总结
    NPOI 插入行[转]
    LINQ语句中的.AsEnumerable() 和 .AsQueryable()的区别 [转]
    Using Google Public DNS[Google公共DNS服务器]
    软件开发知识[TDD]
    MySQL函数之STRCMP()
    MySQL知识[INSERT语法]
    软件开发知识[ORM]
    软件开发知识[ADO.NET Entity Framework]
    mysql workbench 在模板与数据库间同步
  • 原文地址:https://www.cnblogs.com/w-h-h/p/8453004.html
Copyright © 2011-2022 走看看