图论相关
Posted yijiull
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图论相关相关的知识,希望对你有一定的参考价值。
最小生成树:
畅通工程
HDU - 1232只要互相间接通过道路可达即可,说明只要最后是一棵树就可以. 树的边数为顶点数减1.
用并查集求出当前已有的边数, 再用 n-1减去就是还需要再建的路.
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<string> 6 using namespace std; 7 const int maxn=1010; 8 int f[maxn]; 9 int n,m; 10 void init() 11 { 12 for(int i=0;i<=n;i++) 13 f[i]=i; 14 } 15 int gf(int x) 16 { 17 return x==f[x]?x:f[x]=gf(f[x]); 18 } 19 void unit(int x,int y) 20 { 21 int px=gf(x); 22 int py=gf(y); 23 f[px]=py; 24 } 25 26 int main() 27 { 28 while(cin>>n&&n) 29 { 30 cin>>m; 31 int cnt=0; 32 init(); 33 int x,y; 34 for(int i=0;i<m;i++){ 35 cin>>x>>y; 36 if(gf(x)!=gf(y)) {unit(x,y);cnt++;} 37 } 38 cout<<n-1-cnt<<endl; 39 } 40 }
还是畅通工程
HDU - 1233和ppt上讲的一样,就是最小生成树的模板题, 先对边进行排序, 然后用并查集维护一下,就可以了.
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 using namespace std; 5 int f[105]; 6 int n; 7 struct Edge 8 { 9 int x,y,w; 10 bool operator <(const Edge &a)const 11 { 12 return w<a.w; 13 } 14 }e[10010]; 15 void init() 16 { 17 for(int i=0;i<=n;i++) 18 f[i]=i; 19 } 20 int gf(int x) 21 { 22 return x==f[x]?x:f[x]=gf(f[x]); 23 } 24 void unit(int x,int y) 25 { 26 int px=gf(x); 27 int py=gf(y); 28 f[px]=py; 29 } 30 31 int main() 32 { 33 34 while(cin>>n&&n) 35 { 36 init(); 37 int cnt=0; 38 int ans=0; 39 int m=n*(n-1)/2; 40 for(int i=0;i<m;i++) 41 cin>>e[i].x>>e[i].y>>e[i].w; 42 sort(e,e+m); 43 for(int i=0;i<m;i++) 44 { 45 if(gf(e[i].x)!=gf(e[i].y)) { 46 ans+=e[i].w; 47 unit(e[i].x,e[i].y); 48 cnt++; 49 } 50 if(cnt==n-1) break; //已经是树, 跳出循环 51 } 52 cout<<ans<<endl; 53 54 } 55 }
Building a Space Station
POJ - 2031求出任意两点之间的距离减去两个点的半径。
然后求最小生成树.
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<algorithm> 5 using namespace std; 6 const int maxn=110; 7 int n; 8 int f[maxn]; 9 struct node 10 { 11 double x,y,z; 12 double r; 13 }p[maxn]; 14 15 struct edge 16 { 17 int u,v; 18 double w; 19 bool operator < (const edge &a) 20 { 21 return w<a.w; 22 } 23 }e[100010]; 24 25 double getdis(int i,int j) 26 { 27 double dx=p[i].x-p[j].x; 28 double dy=p[i].y-p[j].y; 29 double dz=p[i].z-p[j].z; 30 return sqrt(dx*dx+dy*dy+dz*dz)-p[i].r-p[j].r; 31 } 32 33 void init() 34 { 35 for(int i=0;i<n;i++) 36 f[i]=i; 37 } 38 39 int gf(int a) 40 { 41 return a==f[a]?a:f[a]=gf(f[a]); 42 } 43 44 void uni(int a,int b) 45 { 46 int pa=gf(a); 47 int pb=gf(b); 48 f[pb]=pa; 49 } 50 51 int main() 52 { 53 while(scanf("%d",&n)&&n) 54 { 55 init(); 56 for(int i=0;i<n;i++) 57 { 58 scanf("%lf%lf%lf%lf",&p[i].x,&p[i].y,&p[i].z,&p[i].r); 59 } 60 int cnt=0; 61 for(int i=0;i<n;i++) 62 for(int j=i+1;j<n;j++) 63 { 64 e[cnt].u=i; 65 e[cnt].v=j; 66 e[cnt].w=getdis(i,j); 67 cnt++; 68 } 69 double ans=0; 70 sort(e,e+cnt); 71 for(int i=0;i<cnt;i++) 72 { 73 if(e[i].w<=0) uni(e[i].u,e[i].v); 74 else if(gf(e[i].u)!=gf(e[i].v)) {ans+=e[i].w; uni(e[i].u,e[i].v);} 75 } 76 printf("%.3f\\n",ans); 77 } 78 }
最短路:
有选择的看一下这篇博客: 链接
链式钱向星 链接
Heavy Transportation
POJ - 17971 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<algorithm> 5 using namespace std; 6 const int maxn=1010; 7 int pic[maxn][maxn]; 8 int vis[maxn]; 9 int dc[maxn]; 10 int t,n,m; 11 void dijkstra() 12 { 13 14 15 for(int j=0;j<n;j++) 16 { 17 int m=-1,x; 18 for(int i=1;i<=n;i++) 19 if(!vis[i]&&dc[i]>m) m=dc[x=i]; 20 vis[x]=1; 21 for(int i=1;i<=n;i++) 22 if(!vis[i]&&dc[i]<min(dc[x],pic[x][i])) 23 { 24 dc[i]=min(dc[x],pic[x][i]); 25 } 26 27 } 28 29 30 } 31 32 int main() 33 { 34 scanf("%d",&t); 35 int u,v,w; 36 for(int i=1;i<=t;i++) 37 { 38 scanf("%d%d",&n,&m); 39 memset(pic,0,sizeof(pic)); 40 while(m--) 41 { 42 scanf("%d%d%d",&u,&v,&w); 43 pic[u][v]=pic[v][u]=w; 44 } 45 for(int i=1;i<=n;i++) 46 { 47 vis[i]=0; 48 dc[i]=pic[1][i]; 49 } 50 dijkstra(); 51 printf("Scenario #%d:\\n%d\\n\\n",i,dc[n]); 52 } 53 return 0; 54 55 }
MPI Maelstrom
POJ - 15021 #include<cstdio> 2 #include<cstring> 3 #include<string> 4 #include<iostream> 5 using namespace std; 6 const int inf=0x3f3f3f3f; 7 int pic[110][110]; 8 int vis[110]; 9 int dis[110]; 10 11 int n; 12 13 void dijkstra() 14 { 15 for(int i=1;i<=n;i++){ 16 dis[i]=inf; 17 vis[i]=0; 18 } 19 dis[1]=0; 20 for(int i=0;i<n;i++) 21 { 22 int x,m=inf; 23 for(int y=1;y<=n;y++) if(!vis[y]&&m>dis[y]) m=dis[x=y]; 24 vis[x]=1; 25 for(int y=1;y<=n;y++) if(!vis[y]&&dis[y]>dis[x]+pic[x][y]) dis[y]=dis[x]+pic[x][y]; 26 } 27 } 28 29 int tran(string s) 30 { 31 int len=s.length(); 32 int d=0; 33 for(int i=0;i<len;i++) 34 d=d*10+(s[i]-\'0\'); 35 return d; 36 } 37 int main() 38 { 39 40 int d; 41 string s; 42 while(scanf("%d",&n)!=EOF) 43 { 44 45 for(int i=1;i<=n;i++) 46 for(int j=1;j<=n;j++) 47 pic[i][j]=(i==j?0:inf); 48 for(int i=2;i<=n;i++) 49 for(int j=1;j<i;j++) 50 { 51 cin>>s; 52 if(s=="x") continue; 53 else { 54 55 d=tran(s); 56 pic[i][j]=pic[j][i]=d; 57 } 58 59 60 } 61 dijkstra(); 62 int ans=-1; 63 64 for(int i=2;i<=n;i++) 65 ans=max(ans,dis[i]); 66 printf("%d\\n",ans); 67 } 68 }
Til the Cows Come Home
POJ - 2387优化过的dijkstra
1 #include<cstring> 2 #include<algorithm> 3 #include<queue> 4 using namespace std; 5 const int maxn=1050; 6 const int maxe=5100; 7 int t,n; 8 int head[maxn]; 9 int dis[maxn]; 10 typedef pair<int,int> P; 11 struct node 12 { 13 int v,w,nex; 14 }edge[maxe]; 15 16 int cnt; 17 18 void add(int u,int v,int w) 19 { 20 edge[cnt].v=v; 21 edge[cnt].w=w; 22 edge[cnt].nex=head[u]; 23 head[u]=cnt++; 24 } 25 int dijkstra() 26 { 27 priority_queue<P,vector<P>,greater<P> > pq; 28 P p; 29 node e; 30 int v; 31 for(int i=0;i<=n;i++) 32 dis[i]=999999; 33 dis[n]=0; 34 pq.push(P(0,n)); 35 while(!pq.empty()) 36 { 37 p=pq.top(); 38 pq.pop(); 39 v=p.second; 40 if(dis[v]<p.first) continue; 41 for(int i=head[v];i!=-1;i=edge[i].nex) 42 { 43 e=edge[i]; 44 if(dis[e.v]>e.w+dis[v]) 45 { 46 dis[e.v]=e.w+dis[v]; 47 pq.push(P(dis[e.v],e.v)); 48 } 49 } 50 } 51 printf("%d\\n",dis[1]); 52 } 53 int main() 54 { 55 while(scanf("%d%d",&t,&n)!=EOF) 56 { 57 cnt=0; 58 int u,v,w; 59 memset(head,-1,sizeof(head)); 60 while(t--) 61 { 62 scanf("%d%d%d",&u,&v,&w); 63 add(u,v,w); 64 add(v,u,w); 65 } 66 dijkstra(); 67 68 } 69 }
以上是关于图论相关的主要内容,如果未能解决你的问题,请参考以下文章