首页 > 代码库 > wikioi 1002 搭桥
wikioi 1002 搭桥
题意:这题刚开始看错题意了,原来桥是建在一条直线上就行,不管距离多远。
思路:dfs求第一问答案,然后最小生成树搞,不能建桥的边就设为INF就行了,然后如果用到INF的边就加上0就行了。这样跑一遍最小生成树就是答案。
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<map> #include<queue> #include<set> #include<cmath> #include<bitset> #define mem(a,b) memset(a,b,sizeof(a)) #define lson i<<1,l,mid #define rson i<<1|1,mid+1,r #define llson j<<1,l,mid #define rrson j<<1|1,mid+1,r #define INF 0x7fffffff #define maxn 55 typedef long long ll; typedef unsigned long long ull; using namespace std; int n,m,cnt,vis[maxn][maxn],mm[maxn][maxn],sum; int a[1000005],b[1000005],tmp,sum2,sum3; char s[maxn][maxn]; int dist[8][2]= {1,0,1,1,1,-1,0,1,0,-1,-1,0,-1,1,-1,-1}; int f[1000005]; void dfs(int x,int y,int ans) { for(int i=0; i<8; i++) { int xx=x+dist[i][0],yy=y+dist[i][1]; if(xx>=0&&xx<n&&yy>=0&&yy<m&&!vis[xx][yy]&&s[xx][yy]=='#') { vis[xx][yy]=1; f[mm[xx][yy]]=f[ans]; dfs(xx,yy,ans); } } } int find(int x) { return f[x]==x?x:f[x]=find(f[x]); } struct abc { int u,v,w; bool operator<(const abc &a)const { return w<a.w; } } e[1000005]; void kruscal() { sort(e,e+tmp); int sum=1; for(int i=0; i<tmp&&sum!=cnt; i++) { int x=find(e[i].u),y=find(e[i].v); if(x!=y) { sum++; sum3+=(e[i].w==INF?0:e[i].w); sum2++; f[x]=y; } } } int main() { scanf("%d%d",&n,&m); for(int i=0; i<n; i++) scanf("%s",s[i]); mem(vis,0); cnt=tmp=0; mem(f,0); mem(mm,0); int sum1=0; for(int i=0; i<n; i++) for(int j=0; j<m; j++) if(s[i][j]=='#') { mm[i][j]=++cnt; a[cnt]=i,b[cnt]=j; f[cnt]=cnt; } for(int i=1; i<=cnt; i++) for(int j=i+1; j<=cnt; j++) { e[tmp].u=i,e[tmp].v=j; if(abs(a[i]-a[j])<=1&&abs(b[i]-b[j])<=1) e[tmp++].w=0; else if(abs(a[i]-a[j])<=1) e[tmp++].w=abs(b[i]-b[j])-1; else if(abs(b[i]-b[j])<=1) e[tmp++].w=abs(a[i]-a[j])-1; else e[tmp++].w=INF; } for(int i=0; i<n; i++) for(int j=0; j<m; j++) if(s[i][j]=='#'&&!vis[i][j]) { vis[i][j]=1; dfs(i,j,mm[i][j]); sum1++; } kruscal(); printf("%d\n%d %d\n",sum1,sum2,sum3); return 0; }
wikioi 1002 搭桥
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。