求条
查看原帖
求条
838570
Double_Sheep楼主2024/7/14 16:20

rt,样例已过,谢谢QAQ

#include<bits/stdc++.h>
using namespace std;
const int N = 51,M = 2501;
int n,m,a[N][N],f[M],cnt,cntt,ans,sum,id,CY;
struct ID {int x,y;}Cy[M];
struct edge {int u,v,d;}e[M * M];
bool cmp(edge x,edge y) {
    return x.d < y.d;
}
int find(int x) {
    if(x == f[x]) return x;
    return f[x] = find(f[x]);
}
void kruskal() {
    sort(e + 1,e + cntt + 1,cmp);
    for(int i = 1;i <= cntt;i++) {
        if(find(e[i].u) != find(e[i].v)) {
            f[find(e[i].u)] = find(e[i].v);
            ans++,sum += e[i].d,cnt--;
        }
    }
}
int main() {
    while(1) {
    	scanf("%d%d",&n,&m);
        if(n == 0 && m == 0) break;
        memset(a,0,sizeof(a)); int K = max(n,m);
        cnt = cntt = ans = sum = CY = 0;
        for(int i = 0;i <= K * K + 1;i++) f[i] = i;
        for(int i = 0;i < n;i++) {
            string s; cin >> s;
            for(int j = 1;j <= m;j++) {
                if(s[j - 1] == '#') {
                    a[i + 1][j] = 1,cnt++,Cy[++CY] = ID{i + 1,j};
                    if(i && a[i][j - 1])
                        f[find(i * K + j)] = find((i - 1) * K + j - 1),cnt--;
                    if(i && a[i][j] && !a[i][j - 1])
                        f[find(i * K + j)] = find((i - 1) * K + j),cnt--;
                    if(i && a[i][j + 1] && !a[i][j])
                        f[find(i * K + j)] = find((i - 1) * K + j + 1),cnt--;
                    if(a[i + 1][j - 1] && !a[i][j - 1] && !a[i][j])
                        f[find(i * K + j)] = find(i * K + j - 1),cnt--;
                } else a[i + 1][j] = 0;
            }
        }
		if(id) printf("\n");
        printf("City %d\n",++id);
        if(cnt <= 1) {
            printf("No bridges are needed.\n");
            continue;
        }
        for(int i = 1;i <= CY;i++){
        	int I = Cy[i].x,J = Cy[i].y;
        	for(int ii = I;ii <= n;ii++){
        		for(int k = -1;k <= 1;k++){
        			int II = ii,JJ = J + k,dist = abs(I - II) - 1;
        			if(!a[II][JJ]) continue;
        			if(dist > 0)
        				e[++cntt] = {(I - 1) * K + J,(II - 1) * K + JJ,dist};
				}
			}
        	for(int j = J;j <= m;j++){
        		for(int k = -1;k <= 1;k++){
        			int II = I + k,JJ = j,dist = abs(J - JJ) - 1;
        			if(!a[II][JJ]) continue;
        			if(dist > 0)
        				e[++cntt] = {(I - 1) * K + J,(II - 1) * K + JJ,dist};
				}
			}
		}
        kruskal();
        if(!ans) printf("No bridges are possible.\n");
        else {
            if(ans == 1) printf("%d bridge of total length %d\n",ans,sum);
            else printf("%d bridges of total length %d\n",ans,sum);
        } if(cnt > 1) printf("%d disconnected groups\n",cnt);
    }
    return 0;
}
2024/7/14 16:20
加载中...