• [CF] 37 E. Trial for Chief


    如果固定了一个中心,那么只需要考虑从它开始最远染到的那些点究竟染了几次。

    上下左右不同的点连1边,相同的连0边,跑单源最短路就可以啦。

    lyd讲的是统计到最远黑点+1的最小值,但是#58数据全是白点,嗯...应该这样考虑,黑点+1,白点不+1。

    一开始数组开太大,导致memset时间暴增,没认真估计数据范围呢。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    #define id(x,y) (((x)-1)*m+(y))
    using namespace std;
    
    const int MAXN=2500;
    
    inline int rd() {
        int ret=0,f=1;
        char c;
        while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
        while(isdigit(c))ret=ret*10+c-'0',c=getchar();
        return ret*f;
    }
    
    int n,m;
    
    struct Edge {
        int next,to,w;
    } e[MAXN<<3];
    int ecnt,head[MAXN];
    inline void add(int x,int y,int w) {
    //    printf("Connect:(%d,%d) with (%d,%d) using %d
    ",x/(m+1),x%(m+1),y/(m+1),y%(m+1),w);
        e[++ecnt].next = head[x];
        e[ecnt].to = y;
        e[ecnt].w = w;
        head[x] = ecnt;
    //    e[++ecnt].next = head[y];
    //    e[ecnt].to =x;
    //    e[ecnt].w = w;
    //    head[y] = ecnt;
    }
    
    
    
    char s[64][64];
    
    int dx[4]= {1,0,-1,0};
    int dy[4]= {0,1,0,-1};
    
    int dis[MAXN],inq[MAXN];
    queue<int> Q;
    
    int cnt=0;
    
    int spfa(int st) {
        memset(dis,0x3f,sizeof(dis));
        int ret=0;
        dis[st]=0;
        Q.push(st);
        inq[st]=1;
        while(!Q.empty()) {
            int top=Q.front();
            Q.pop();
            inq[top]=0;
            for(int i=head[top]; i; i=e[i].next) {
                int v=e[i].to;
                if(dis[v]>dis[top]+e[i].w) {
                    dis[v]=dis[top]+e[i].w;
                    if(!inq[v]) Q.push(v),inq[v]=1;
                }
            }
        }
        for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) 
        if(s[i][j]=='B') ret=max(ret,1+dis[id(i,j)]);
        else ret=max(ret,dis[id(i,j)]);
        return ret;
    }
    
    int main() {
        n=rd();
        m=rd();
        for(int i=1; i<=n; i++) {
            scanf("%s",s[i]+1);
        }
        int x,y;
        for(int i=1; i<=n; i++) {
            for(int j=1; j<=m; j++) {
                for(int k=0; k<=3; k++) {
                    x=i+dx[k],y=j+dy[k];
                    if(x<1||x>n||y<1||y>m) continue;
                    if(s[x][y]==s[i][j]) add(id(i,j),id(x,y),0);
                    else add(id(i,j),id(x,y),1);
                }
            }
        }
        int ans=1<<30;
        for(int i=1; i<=n; i++) {
            for(int j=1; j<=m; j++) {
                ans=min(ans,spfa(id(i,j)));
            }
        }
        printf("%d",ans);
        cout<<endl;
        return 0;
    }

    本文来自博客园,作者:GhostCai,转载请注明原文链接:https://www.cnblogs.com/ghostcai/p/9275498.html

  • 相关阅读:
    bzoj 4583 购物
    hdu 4694 支配树
    弦图问题初步
    第一次省选总结
    初学kd树
    省选前集训 lca
    bzoj 3282 Tree
    bzoj 2157 旅游
    二分图匹配(匈牙利算法模板)
    最大流(模板)
  • 原文地址:https://www.cnblogs.com/ghostcai/p/9275498.html
Copyright © 2020-2023  润新知