牛的旅行
#include<bits/stdc++.h> using namespace std; int read(){ int f=1,x=0; char c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48); c=getchar();} return f*x; } int n,cnt,hd[160],vis[160]; double dis[160],B[160],D[160]; char c; bool b[160]; struct plac{ int x,y; }a[160]; struct node{ int to,nxt; double l; }edge[50000]; double dist(int xa,int xb,int ya,int yb){ return sqrt((xa-xb)*(xa-xb)+(ya-yb)*(ya-yb)); } void add(int u,int v){ cnt++; edge[cnt].to=v; edge[cnt].nxt=hd[u]; edge[cnt].l=dist(a[u].x,a[v].x,a[u].y,a[v].y); hd[u]=cnt; } void dfs(int u,int col){ if(vis[u]) return; vis[u]=col; for(int i=hd[u];i;i=edge[i].nxt) dfs(edge[i].to,col); } struct nod{ double l; int d; bool operator<(const nod &w)const{ return l>w.l; } }; priority_queue<nod> q; void dij(int st){ for(int i=1;i<=n;i++) dis[i]=1000000000; memset(b,0,sizeof(b)); q.push((nod){0,st}); dis[st]=0; while(!q.empty()){ int tp=q.top().d; q.pop(); if(b[tp]) continue; b[tp]=1; for(int i=hd[tp];i;i=edge[i].nxt){ int v=edge[i].to; double w=edge[i].l; if(dis[v]>dis[tp]+edge[i].l){ dis[v]=dis[tp]+edge[i].l; q.push((nod){dis[v],v}); } } } int t; double mx=-1; for(int i=1;i<=n;i++){ if(vis[i]==cnt) B[st]=max(B[st],dis[i]); } D[cnt]=max(D[cnt],B[st]); } double ans=2147483647; int main(){ n=read(); for(int i=1;i<=n;i++){ a[i].x=read(); a[i].y=read(); } getchar(); for(int i=1;i<=n;i++){ int j = 0; while(c = getchar()){ if(c != '0' && c != '1') break; ++j; if(c == '1'){ add(i,j); cout<<"i,j "<<i<<" "<<j<<endl; } } getchar(); } cnt=0;//可回收垃圾 for(int i=1;i<=n;i++){ if(!vis[i]){//这个点在一个新的集合 dfs(i,++cnt);//把这个集合里所有的点找出来染色 for(int j=1;j<=n;j++){ if(vis[j]==cnt) dij(j);//这个集合里每个点都当一次与外部连接的点 } } } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(vis[i]==vis[j]) continue;//一个集合内就不连了 ans=min(ans,max(dist(a[i].x,a[j].x,a[i].y,a[j].y)+B[i]+B[j],max(D[vis[i]],D[vis[j]])));//答案就是所有可连接的点中连线的长度再加上两个牧场原来与这些点连接的最长长度(还有两个联通块的直径) } } printf("%.6lf",ans); return 0; }
wa代码:
#include<bits/stdc++.h> using namespace std; int read(){ int f=1,x=0; char c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48); c=getchar();} return f*x; } int n,cnt,hd[160],vis[160]; double dis[160],B[160],D[160]; char c; bool b[160]; struct plac{ int x,y; }a[160]; struct node{ int to,nxt; double l; }edge[50000]; double dist(int xa,int xb,int ya,int yb){ return sqrt((xa-xb)*(xa-xb)+(ya-yb)*(ya-yb)); } void add(int u,int v){ cnt++; edge[cnt].to=v; edge[cnt].nxt=hd[u]; edge[cnt].l=dist(a[u].x,a[v].x,a[u].y,a[v].y); hd[u]=cnt; } void dfs(int u,int col){ if(vis[u]) return; vis[u]=col; for(int i=hd[u];i;i=edge[i].nxt) dfs(edge[i].to,col); } struct nod{ double l; int d; bool operator<(const nod &w)const{ return l>w.l; } }; priority_queue<nod> q; void dij(int st){ for(int i=1;i<=n;i++) dis[i]=1000000000; memset(b,0,sizeof(b)); q.push(nod{0,st}); dis[st]=0; while(!q.empty()){ int tp=q.top().d; q.pop(); if(b[tp]) continue; b[tp]=1; for(int i=hd[tp];i;i=edge[i].nxt){ int v=edge[i].to; double w=edge[i].l; if(dis[v]>dis[tp]+edge[i].l){ dis[v]=dis[tp]+edge[i].l; q.push(nod{dis[v],v}); } } } int t; double mx=-1; for(int i=1;i<=n;i++){ if(vis[i]==cnt) B[st]=max(B[st],dis[i]); } D[cnt]=max(D[cnt],B[st]); } double ans=2147483647; int main(){ n=read(); for(int i=1;i<=n;i++){ a[i].x=read(); a[i].y=read(); } for(int i=1;i<=n;i++){ for(int j=1;j<=n+1;j++){ c=getchar(); if(c=='\n') continue; if(c=='1') add(i,j);//连接两个点 } } cnt=0;//可回收垃圾 for(int i=1;i<=n;i++){ if(!vis[i]){//这个点在一个新的集合 dfs(i,++cnt);//把这个集合里所有的点找出来染色 for(int j=1;j<=n;j++){ if(vis[j]==cnt) dij(j);//这个集合里每个点都当一次与外部连接的点 } } } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(vis[i]==vis[j]) continue;//一个集合内就不连了 ans=min(ans,max(dist(a[i].x,a[j].x,a[i].y,a[j].y)+B[i]+B[j],max(D[vis[i]],D[vis[j]])));//答案就是所有可连接的点中连线的长度再加上两个牧场原来与这些点连接的最长长度(还有两个联通块的直径) } } printf("%.6lf",ans); return 0; }
正行读入:
#include<bits/stdc++.h> using namespace std; int read(){ int f=1,x=0; char c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48); c=getchar();} return f*x; } int n,cnt,hd[160],vis[160]; double dis[160],B[160],D[160]; char c; bool b[160]; string s; struct plac{ int x,y; }a[160]; struct node{ int to,nxt; double l; }edge[50000]; double dist(int xa,int xb,int ya,int yb){ return sqrt((xa-xb)*(xa-xb)+(ya-yb)*(ya-yb)); } void add(int u,int v){ cnt++; edge[cnt].to=v; edge[cnt].nxt=hd[u]; edge[cnt].l=dist(a[u].x,a[v].x,a[u].y,a[v].y); hd[u]=cnt; } void dfs(int u,int col){ if(vis[u]) return; vis[u]=col; for(int i=hd[u];i;i=edge[i].nxt) dfs(edge[i].to,col); } struct nod{ double l; int d; bool operator<(const nod &w)const{ return l>w.l; } }; priority_queue<nod> q; void dij(int st){ for(int i=1;i<=n;i++) dis[i]=1000000000; memset(b,0,sizeof(b)); q.push((nod){0,st}); dis[st]=0; while(!q.empty()){ int tp=q.top().d; q.pop(); if(b[tp]) continue; b[tp]=1; for(int i=hd[tp];i;i=edge[i].nxt){ int v=edge[i].to; double w=edge[i].l; if(dis[v]>dis[tp]+edge[i].l){ dis[v]=dis[tp]+edge[i].l; q.push((nod){dis[v],v}); } } } int t; double mx=-1; for(int i=1;i<=n;i++){ if(vis[i]==cnt) B[st]=max(B[st],dis[i]); } D[cnt]=max(D[cnt],B[st]); } double ans=2147483647; int main(){ // freopen("travel4.in","r",stdin); n=read(); for(int i=1;i<=n;i++){ a[i].x=read(); a[i].y=read(); } getchar();//windows下多余的符号 for(int i = 1; i <= n; i++){ getline(cin,s); for(int j = 1; j <= n; j++) if(s[j-1] == '1') add(i,j); } cnt=0;//可回收垃圾 for(int i=1;i<=n;i++){ if(!vis[i]){//这个点在一个新的集合 dfs(i,++cnt);//把这个集合里所有的点找出来染色 for(int j=1;j<=n;j++){ if(vis[j]==cnt) dij(j);//这个集合里每个点都当一次与外部连接的点 } } } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(vis[i]==vis[j]) continue;//一个集合内就不连了 ans=min(ans,max(dist(a[i].x,a[j].x,a[i].y,a[j].y)+B[i]+B[j],max(D[vis[i]],D[vis[j]])));//答案就是所有可连接的点中连线的长度再加上两个牧场原来与这些点连接的最长长度(还有两个联通块的直径) } } printf("%.6lf",ans); return 0; }
#include<bits/stdc++.h>using namespace std;int read(){int f=1,x=0; char c=getchar();while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48); c=getchar();}return f*x;}int n,cnt,hd[160],vis[160];double dis[160],B[160],D[160];char c;bool b[160];string s;struct plac{int x,y;}a[160];struct node{int to,nxt;double l;}edge[50000];double dist(int xa,int xb,int ya,int yb){return sqrt((xa-xb)*(xa-xb)+(ya-yb)*(ya-yb));}void add(int u,int v){cnt++;edge[cnt].to=v;edge[cnt].nxt=hd[u];edge[cnt].l=dist(a[u].x,a[v].x,a[u].y,a[v].y);hd[u]=cnt;}void dfs(int u,int col){if(vis[u]) return;vis[u]=col;for(int i=hd[u];i;i=edge[i].nxt) dfs(edge[i].to,col);}struct nod{double l;int d;bool operator<(const nod &w)const{return l>w.l;}};priority_queue<nod> q;void dij(int st){for(int i=1;i<=n;i++) dis[i]=1000000000;memset(b,0,sizeof(b));q.push((nod){0,st});dis[st]=0;while(!q.empty()){int tp=q.top().d;q.pop();if(b[tp]) continue;b[tp]=1;for(int i=hd[tp];i;i=edge[i].nxt){int v=edge[i].to;double w=edge[i].l;if(dis[v]>dis[tp]+edge[i].l){dis[v]=dis[tp]+edge[i].l;q.push((nod){dis[v],v});}}}int t;double mx=-1;for(int i=1;i<=n;i++){if(vis[i]==cnt) B[st]=max(B[st],dis[i]);}D[cnt]=max(D[cnt],B[st]);}double ans=2147483647;int main(){//freopen("travel4.in","r",stdin); n=read();for(int i=1;i<=n;i++){a[i].x=read();a[i].y=read();}getchar();//windows下多余的符号 for(int i = 1; i <= n; i++){getline(cin,s);for(int j = 1; j <= n; j++)if(s[j-1] == '1') add(i,j);}cnt=0;//可回收垃圾 for(int i=1;i<=n;i++){if(!vis[i]){//这个点在一个新的集合 dfs(i,++cnt);//把这个集合里所有的点找出来染色 for(int j=1;j<=n;j++){if(vis[j]==cnt) dij(j);//这个集合里每个点都当一次与外部连接的点 }}}for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){if(vis[i]==vis[j]) continue;//一个集合内就不连了 ans=min(ans,max(dist(a[i].x,a[j].x,a[i].y,a[j].y)+B[i]+B[j],max(D[vis[i]],D[vis[j]])));//答案就是所有可连接的点中连线的长度再加上两个牧场原来与这些点连接的最长长度(还有两个联通块的直径)}}printf("%.6lf",ans);return 0;}