zoukankan      html  css  js  c++  java
  • bzoj2547: [Ctsc2002]玩具兵

    划了一天水,其实我还是有点愧疚的。

    传送门

    其实是水题,然而我真是太蠢了。。。

    首先不考虑天兵,其他兵要到一个点去一定是通过它-另一种兵-它……这样多次交换的,并且交换对象是无所谓的,和它换的兵最终会是在原位置。

    而且骑兵和步兵的数量相等,就不存在一个兵找不到人跟它换的情况,那么一个确定的方案下换的次数最多的兵换的次数就是答案。

    先spfa找出每个兵到每个位置的最小换的次数,然后二分答案,把每个兵向它可以到的地方连边,跑最大匹配,考虑到还有天兵,而天兵是可以一步登天的超神存在,所以如果最大匹配数+现在check的ans>=总兵数即OK。

    因为一直在划水,断断续续地写这个代码 ,又困得要命,仿佛活在梦中,结果竟然1A了,神奇。

    //Achen
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<vector>
    #include<cstdio>
    #include<queue>
    #include<cmath>
    const int N=107; 
    typedef long long LL;
    using namespace std;
    int n,m,k,t,R[N],h[N][N],dis[N][N],dp[N][N][2],vis[N][N][2];
    int dx[5]={0,0,1,-1},dy[5]={1,-1,0,0};
    
    template<typename T>void read(T &x)  {
        char ch=getchar(); x=0; T f=1;
        while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
        if(ch=='-') f=-1,ch=getchar();
        for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    }
    
    struct node    {
        int x,y,o;
        node(){}
        node(int x,int y,int o):x(x),y(y),o(o){}
    }b[N],p[N];
    
    queue<node>que;
    void spfa(int sx,int sy,int k) {
        memset(dp,127,sizeof(dp));
        if(k) dp[sx][sy][0]=0,que.push(node(sx,sy,0));
        else dp[sx][sy][1]=0,que.push(node(sx,sy,1));
        while(!que.empty()) {
            node now=que.front();
            que.pop();
            int x=now.x,y=now.y,o=now.o;
            vis[x][y][o]=0;
            for(int i=0;i<4;i++) {
                int xx=now.x+dx[i],yy=now.y+dy[i],oo,t;
                if(xx>=1&&xx<=n&&yy>=1&&yy<=m) {
                    if((o==0&&h[xx][yy]>=h[x][y])||(o==1&&h[xx][yy]<=h[x][y])) t=dp[x][y][o],oo=o;
                    else t=dp[x][y][o]+1,oo=o^1;
                    if(dp[xx][yy][oo]>t) {
                        dp[xx][yy][oo]=t;
                        if(!vis[xx][yy][oo]) {
                            que.push(node(xx,yy,oo));
                            vis[xx][yy][oo]=1;
                        }
                    }
                }
            }
        }
    }
    
    int ok[N][N],vs[N],pr[N],sum[N];
    int find(int x) {
        for(int i=1;i<=2*k;i++) if(ok[x][i]&&!vs[i]) {
            vs[i]=1;
            if(!pr[i]||find(pr[i])) {
                pr[i]=x; 
                return 1;
            } 
        }
        return 0;
    }
    
    int ck(int ans) {
         int res=0;
         for(int i=1;i<=2*k;i++) 
             for(int j=1;j<=t;j++) {
                if(dis[i][j]<=ans) 
                    for(int kk=1;kk<=R[j];kk++) 
                        ok[i][sum[j-1]+kk]=1;
                else for(int kk=1;kk<=R[j];kk++) 
                    ok[i][sum[j-1]+kk]=0;
            }
        memset(pr,0,sizeof(pr));
        for(int i=1;i<=2*k;i++) {
            memset(vs,0,sizeof(vs));
            if(find(i)) res++;
        }
        if(res+ans>=2*k) return 1;
        else return 0;
    }
    
    int main() {
        read(n); read(m); read(k); read(t);
        for(int i=1;i<=2*k+1;i++) { 
            read(b[i].x); 
            read(b[i].y); 
        }
        for(int i=1;i<=t;i++) { 
            read(p[i].x); 
            read(p[i].y); 
            read(R[i]); sum[i]=sum[i-1]+R[i];
        }
        for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) read(h[i][j]);
        memset(dis,127,sizeof(dis));
        for(int i=1;i<=2*k;i++) {
            spfa(b[i].x,b[i].y,(i<=k));
            for(int j=1;j<=t;j++) 
                dis[i][j]=min(dp[p[j].x][p[j].y][0],dp[p[j].x][p[j].y][1]);
        }
        if(ck(0)) {
            puts("0"); return 0;
        }
        int l=1,r=1e9,ans=r;
        while(l<=r) {
            int mid=((l+r)>>1);
            if(ck(mid)) ans=mid,r=mid-1;
            else l=mid+1;
        }
        printf("%d
    ",ans);
        return 0;
    }
    /*
    4 6 2 5
    1 1   1 5   4 1   4 5    3 3
    1 2 1   2 6 1   3 2 1   3 6 1   4 3 1
    3 2 6 1 3 5
    2 1 7 4 4 6
    2 3 1 4 3 4
    4 3 4 3 2 3
    */
    View Code
  • 相关阅读:
    POJ 1795 DNA Laboratory
    CodeForces 303B Rectangle Puzzle II
    HDU 2197 本源串
    HDU 5965 扫雷
    POJ 3099 Go Go Gorelians
    CodeForces 762D Maximum path
    CodeForces 731C Socks
    HDU 1231 最大连续子序列
    HDU 5650 so easy
    大话接口隐私与安全 转载
  • 原文地址:https://www.cnblogs.com/Achenchen/p/8414201.html
Copyright © 2011-2022 走看看