标签:统计 || namespace 导致 \n mem queue push name
如果固定了一个中心,那么只需要考虑从它开始最远染到的那些点究竟染了几次。
上下左右不同的点连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; }
标签:统计 || namespace 导致 \n mem queue push name
原文地址:https://www.cnblogs.com/ghostcai/p/9275498.html