1. 程式人生 > >[CF] 37 E. Trial for Chief

[CF] 37 E. Trial for Chief

urn nec spf push char mes isdigit color ron

如果固定了一個中心,那麽只需要考慮從它開始最遠染到的那些點究竟染了幾次。

上下左右不同的點連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\n",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; }

[CF] 37 E. Trial for Chief