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
  • 相关阅读:
    MVC的一个分页,网上摘录,自己少量修改
    Hibernate调用带返回值的存储过程的方法
    让tomcat启动后自动进行一些操作
    Java中汉字转拼音
    [转]asp.net response.ContentType 下载文件的四种方法
    [转]c3p0详细配置
    js替换换行
    JS省市区联动,可由数据库提取数据至JS
    silverlight导入文件到WebService
    Java生成Guid
  • 原文地址:https://www.cnblogs.com/Achenchen/p/8414201.html
Copyright © 2011-2022 走看看