Calculate the absolute center & minimum diameter spanning tree mdst of an image

Source: Internet
Author: User

Recommendation http://www.csie.ntnu.edu.tw /~ U91029/spanningtree.html # A7

Last written binary, http://blog.csdn.net/haha593572013/article/details/8538216

Reference lzqxh written: http://www.cnblogs.com/lzqxh/archive/2013/03/05/2944834.html#2659117

Question Link

Http://www.spoj.com/problems/MDST/

Http://acm.timus.ru/problem.aspx? Space = 1 & num = 1569

Http://www.spoj.com/problems/PT07C/

Make a record by yourself ..

I used this question for the last time. Today I saw a better algorithm, so I learned it...

The absolute center of an image is such a point. It can exist on any side, and the maximum value of the shortest distance from this point to all points is the smallest.

First, we can prove that the maximum distance from the absolute center to all vertices will certainly be two, and the two shortest distances are located at both ends of an edge, that is, adding the absolute center to the edge of U v, there must be two shortest paths with the same distance and the maximum. One path is from the absolute center to the U direction, and the other path is from the absolute center to the V direction... This can be YY, assuming what, and then conflict...

Then we enumerate each edge. If the absolute center is on this edge, the shortest distance from the center to a point can be expressed as Min (d [u] [s] + X, d [v] [s] + L-x). If you draw a function image, it is a line. Take a minimum value on this line, that is, the minimum value of the shortest distance from the center to S, so that every point is such a line, because we need to take the maximum value of the shortest distance, so we need to take the lowest point on the top line of all the broken lines. We can see the figure below.

Sort d [u] [W] and scan it to find all the intersections. The problem was solved perfectly.

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int inf = ~0u>>2;const int MAX_N  = 210;int d[MAX_N][MAX_N],di[MAX_N][MAX_N];int rk[MAX_N][MAX_N];int main(){int n , m , a , b , c;scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){d[i][i] = 0;  di[i][i] = 0;for(int j=i+1;j<=n;j++){di[i][j] = di[j][i] = inf;d[i][j] = d[j][i] = inf;}}for(int i=0;i<m;i++){scanf("%d%d%d",&a,&b,&c);d[a][b] = d[b][a] = c;di[a][b] = di[b][a] = c;}for(int k=1;k<=n;k++){for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){d[i][j] = min(d[i][j],d[i][k]+d[k][j]);}}}for(int i=1;i<=n;i++){for(int j=1;j<=n;j++)  rk[i][j] = j;for(int j=1;j<=n;j++){for(int k=j+1;k<=n;k++){if(d[i][rk[i][j]] > d[i][rk[i][k]]){swap(rk[i][j],rk[i][k]);}}}}int ans = inf;for(int u=1;u<=n;u++){for(int v=1;v<=n;v++) if(u!=v){ans = min(ans,d[u][rk[u][n]]<<1);ans = min(ans,d[v][rk[v][n]]<<1);for(int cmp=n,i=n-1;i>=1;i--){if(d[v][rk[u][i]] > d[v][rk[u][cmp]]){ans = min(ans,d[u][rk[u][i]]+d[v][rk[u][cmp]]+di[u][v]);cmp = i;}}}}printf("%lf\n",(double)ans/2);return 0;}

Timus 1569

Here is a graph that asks you for mdst, that is, the smallest diameter spanning tree. The farthest distance between the two vertices of this tree is the smallest of all spanning trees.

In fact, we need to first find the absolute center, and then start from the absolute center, and find a shortest path tree. This is simple. The Edge Weight is 1, and direct BFS is also acceptable.

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int inf = ~0u>>2;const int MAX_N  = 210;int d[MAX_N][MAX_N],di[MAX_N][MAX_N];int rk[MAX_N][MAX_N];int n , m ,s1 ,s2;void Floyd(){for(int k=1;k<=n;k++)for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)d[i][j] = min(d[i][j],d[i][k]+d[k][j]);}void Find_Center(){for(int i=1;i<=n;i++){for(int j=1;j<=n;j++)  rk[i][j] = j;for(int j=1;j<=n;j++){for(int k=j+1;k<=n;k++){if(d[i][rk[i][j]] > d[i][rk[i][k]]){swap(rk[i][j],rk[i][k]);}}}}int ans = inf;s1 = - 1,s2 = -1;for(int u=1;u<=n;u++){for(int v=1;v<=n;v++) if(di[u][v]!=-1){//ans = min(ans,d[u][rk[u][n]]<<1);//ans = min(ans,d[v][rk[v][n]]<<1);int a1 = d[u][rk[u][n]]<<1 , a2 = d[v][rk[v][n]]<<1;if(a1 < ans) {ans=a1;s1=s2=u;}if(a2 < ans) {ans=a2;s1=s2=v;}for(int cmp=n,i=n-1;i>=1;i--){if(d[v][rk[u][i]] > d[v][rk[u][cmp]]){int tmp = d[u][rk[u][i]]+d[v][rk[u][cmp]]+di[u][v];if(tmp < ans ){ans = tmp;s1 = u;s2 = v;}cmp = i;}}}}}bool vis[MAX_N];int dis[MAX_N];int pre[MAX_N];int Q[MAX_N];void spfa(){fill(vis,vis+n+1,false);    fill(dis,dis+n+1,inf);fill(pre,pre+n+1,-1);int head = 0, tail = 0 , tmp;vis[s1] = true;dis[s1] = 0;Q[++tail]=s1;if(s1!=s2){Q[++tail]=s2;vis[s2]=true;dis[s2]=0;pre[s2]=s1;}while(head<tail){int fr = Q[++head]; vis[fr] = false;for(int i=1;i<=n;i++) if(di[fr][i]!=-1){tmp = dis[fr] + di[fr][i];if(tmp < dis[i]) {dis[i] = tmp;pre[i] = fr;if(!vis[i]) {vis[i] =true;Q[++tail] = i;}}}}}void solve(){Floyd();    Find_Center();spfa();}int main(){int a , b , c;scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){d[i][i] = 0;  for(int j=i+1;j<=n;j++){d[i][j] = d[j][i] = inf;}}memset(di,-1,sizeof(di));for(int i=0;i<m;i++){scanf("%d%d",&a,&b);d[a][b] = d[b][a] = 1;di[a][b] = di[b][a] = 1;}solve();for(int i=1;i<=n;i++) if(pre[i]!=-1){printf("%d %d\n",i,pre[i]);}return 0;}

735. minimum diameter spanning tree

Like the above questions, the core is to find the absolute center of the tree ,...

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int inf = ~0u>>2;const int MAX_N  = 1010;const int MAX_E = 10010;int d[MAX_N][MAX_N],di[MAX_N][MAX_N];int rk[MAX_N][MAX_N];int n , m ,s1 ,s2;int Q[100010];bool vis[MAX_N];int H[MAX_N], nxt[MAX_E*3] , pnt[MAX_E*3] ;int dis[MAX_N];int E;void add(int a,int b){pnt[E] = b;nxt[E] = H[a];H[a] = E++;}void spfa(int s){fill(vis,vis+n+1,false);fill(dis,dis+n+1,inf);int head = 0, tail = 0;Q[++tail] = s;vis[s] = true;dis[s] = 0;while(head<tail){int fr = Q[++head];for(int i=H[fr];i!=-1;i=nxt[i]){if(vis[pnt[i]]) continue;dis[pnt[i]] =  dis[fr] + 1;;vis[pnt[i]] = true;Q[++tail] = pnt[i];}}}void shortest_path(){for(int i=1;i<=n;i++){spfa(i);for(int j=1;j<=n;j++){d[i][j] = dis[j];}}}struct Edge{int s,t;}edge[100010];int now;int cmp(int i,int j){return  d[now][i] < d[now][j];}inline int min(int a,int b) {return a<b?a:b;}void Find_Center(){for(int i=1;i<=n;i++){for(int j=1;j<=n;j++)  rk[i][j] = j;now = i;sort(rk[i]+1,rk[i]+n+1,cmp);}int ans = inf;s1 = - 1,s2 = -1;for(int e=0;e<m;e++){int u = edge[e].s , v = edge[e].t;if(di[u][v]==-1) continue;ans=min(ans, d[u][rk[u][n]]<<1);ans=min(ans, d[v][rk[v][n]]<<1);for(int cmp=n,i=n-1;i>=1;i--){if(d[v][rk[u][i]] > d[v][rk[u][cmp]]){int tmp = d[u][rk[u][i]]+d[v][rk[u][cmp]]+di[u][v];if(tmp < ans )ans = tmp;cmp = i;}}}printf("%d\n",ans==inf?0:ans);}void solve(){shortest_path();Find_Center();}int main(){int t;int a , b , c;scanf("%d",&t);while(t--) {scanf("%d",&n);E=0; m = 0;fill(H,H+n+1,-1);fill(d[1],d[n+1],-1);for(int i=1,k;i<=n;i++){scanf("%*d%d",&k);for(int j=0,x;j<k;j++){scanf("%d",&x);add(x,i);add(i,x);edge[m].s = i;edge[m++].t = x;di[i][x] = di[x][i] = 1;}}solve();}return 0;}

Spoj 1479

This question is a weighted mdst problem. After a whole day, I finally found an error... Remind future generations...

If you find the edge of the absolute center, the edge must be on the spanning tree, that is, the shortest path tree should be constructed around this edge, first, I put the two vertices into the queue, and then dis [S1] = 0, DIS [s2] = W [S1] [s2],

Pre [s2] = S1;

However, note that if this problem occurs, DIS [s2] will be updated during spfa execution, and the answer is incorrect. The S1 S2 edge may be missing. Therefore, the value of DIS [S1] dis [s2] must be a real value. If we change it to double, we will be able to remember the actual value, and then we will be able to afford it .......

#include<cstdio>#include<cstring>#include<iostream>#include<vector>#include<algorithm>using namespace std;typedef long long lld;const int inf = 1000000000;const int MAX_N  = 210;int d[MAX_N][MAX_N];int di[MAX_N][MAX_N];int rk[MAX_N][MAX_N];int n , m ,s1 ,s2;void Floyd(){for(int k=1;k<=n;k++)for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)d[i][j] = min(d[i][j],d[i][k]+d[k][j]);}double dis[MAX_N];void Find_Center(){for(int i=1;i<=n;i++){for(int j=1;j<=n;j++)  rk[i][j] = j;for(int j=1;j<=n;j++){for(int k=j+1;k<=n;k++){if(d[i][rk[i][j]] > d[i][rk[i][k]]){swap(rk[i][j],rk[i][k]);}}}}int ans = inf;s1 = - 1,s2 = -1;for(int u=1;u<=n;u++){if(d[u][rk[u][n]]*2<ans){ans = d[u][rk[u][n]]*2;s1 = s2 = u;dis[s1] = 0;}for(int v=1;v<=n;v++) if(di[u][v]!=-1){for(int cmp=n,i=n-1;i>=1;i--){if(d[v][rk[u][i]] > d[v][rk[u][cmp]]){int tmp = d[u][rk[u][i]]+d[v][rk[u][cmp]]+di[u][v];if(tmp < ans ){ans = tmp;s1 = u;s2 = v;dis[s1] = (double)tmp/2-d[u][rk[u][i]];dis[s2] = (double)di[u][v] - dis[s1];}cmp = i;}}}}printf("%d\n",ans);}bool vis[MAX_N];int pre[MAX_N];int Q[2000010];void spfa(){fill(vis,vis+n+1,false);    for(int i=1;i<=n;i++) if(i!=s1&&i!=s2) dis[i] = inf;fill(pre,pre+n+1,-1);int head = 0, tail = 0 , tmp;vis[s1] = true;Q[++tail]=s1;if(s1!=s2){Q[++tail]=s2;vis[s2]=true;pre[s2]=s1;}while(head<tail){int fr = Q[++head]; vis[fr] = false;for(int i=1;i<=n;i++) if(di[fr][i]!=-1){tmp = dis[fr] + di[fr][i];if(tmp < dis[i]) {dis[i] = tmp;pre[i] = fr;if(!vis[i]) {vis[i] =true;Q[++tail] = i;}}}}}void solve(){Floyd();    Find_Center();spfa();}int main(){int a , b , c;scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){d[i][i] = 0;   for(int j=i+1;j<=n;j++){d[i][j] = d[j][i] = inf;}}memset(di,-1,sizeof(di));for(int i=0;i<m;i++){scanf("%d%d%d",&a,&b,&c);if(a==b) continue;if(c<d[a][b]){d[a][b] = d[b][a] = c;di[a][b] = di[b][a] = c;}}solve();int cnt = 0;vector<pair<int,int> > ret;for(int i=1;i<=n;i++) if(pre[i]!=-1){cnt++;if(i<pre[i])  ret.push_back(make_pair(i,pre[i]));else ret.push_back(make_pair(pre[i],i));}sort(ret.begin(),ret.end());for(int i=0;i<ret.size();i++){printf("%d %d\n",ret[i].first,ret[i].second);}return 0;}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.