UESTC 888 Absurdistan Roads (kruscal+floyd)

(o(╯□╰)o还是很不习惯国外的区域赛题目。。。读不是很懂啊不是很懂啊。。。要研究半天)

Absurdistan Roads

Time Limit: 5678/3456MS (Java/Others)     Memory Limit: 65432/65432KB (Java/Others)

Submit 
Status

The people of Absurdistan discovered how to build roads only last year. After the discovery, every city decided to build their own road connecting their city with another city. Each newly built road can be used
in both directions.

Absurdistan is full of surprising coincidences. It took all N cities
precisely one year to build their roads. And even more surprisingly, in the end it was possible to travel from every city to every other city using the newly built roads.

You bought a tourist guide which does not have a map of the country with the new roads. It only contains a huge table with the shortest distances between all pairs of cities using the newly built roads. You would
like to know between which pairs of cities there are roads and how long they are, because you want to reconstruct the map of the N newly
built roads from the table of shortest distances.

You get a table of shortest distances between all pairs of cities in Absurdistan using the N roads
built last year. From this table, you must reconstruct the road network of Absurdistan. There might be multiple road networks with N roads
with that same table of shortest distances, but you are happy with any one of those networks.

Input

For each test case:

  • A line containing an integer N (2≤N≤2000) --
    the number of cities and roads.
  • N lines
    with N numbers
    each. The j-th
    number of the i-th
    line is the shortest distance from city i to
    city j.
    All distances between two distinct cities will be positive and at most 1000000.
    The distance from i to i will
    always be 0 and
    the distance from i to j will
    be the same as the distance from j to i.

Output

For each test case:

  • Print N lines
    with three integers ‘a b c‘
    denoting that there is a road between cities 1≤a≤N and 1≤b≤N of
    length 1≤c≤1000000,
    wherea≠b.
    If there are multiple solutions, you can print any one and you can print the roads in any order. At least one solution is guaranteed to exist.

Print a blank line between every two test cases.

Sample input and output

Sample Input Sample Output
4
0 1 2 1
1 0 2 1
2 2 0 1
1 1 1 0
4
0 1 1 1
1 0 2 2
1 2 0 2
1 2 2 0
3
0 4 1
4 0 3
1 3 0
2 1 1
4 1 1
4 2 1
4 3 1

2 1 1
3 1 1
4 1 1
2 1 1

3 1 1
2 1 4
3 2 3

Source

Northwestern European Regional Contest 2013

题意:

就是给一张n个点的矩阵,pos[i][j]表示i和j之间的最短距离。要你将新建的道路满足这个table最短距离描述

的n条所建的边输出且保证这些边权是最小的。

算法:

先用kruscal找到最小的n-1条边把所有点连通,这n-1条边是肯定符合要求的。然后利用这n-1条边的边权用

floyd求n个点两两之间能形成的最短路。再把边从小到大扫描,如果与table中的最短路不符,则为第n条要建的

边,否则就从前n-1条边中任意输出一条。

有几个地方要注意剪枝,不然特别容易TLE。。。

1、从第n-1条(由于我存边的编号从0开始,即为编号n-2的边)开始判断是否相符。

2、floyd要判断if(mp2[i][k]==INF) 直接break。

3、kruscal那个从0-cnt的遍历哟。。。到了c==n-1就可以break了。。。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define INF 0x3f3f3f3f
#define maxn 2010

using namespace std;

int mp[maxn][maxn],n,cnt,fa[maxn],mp2[maxn][maxn];
bool vis[maxn][maxn];
struct node
{
    int u,v,w;
}e[maxn*maxn],ans[maxn+10];

void add(int x,int y,int z)
{
    e[cnt].u = x;
    e[cnt].v = y;
    e[cnt++].w = z;
}
bool cmp(node x,node y)
{
    return x.w<y.w;
}
int find(int x)
{
    return fa[x]==x?x:find(fa[x]);
}
void init()
{
    for(int i=1;i<=n;i++)
        fa[i] = i;
    cnt = 0;
}
bool merge(int a,int b)
{
    int fx = find(a);
    int fy = find(b);
    if(fx!=fy)
    {
        fa[fx] = fy;
        return true;
    }
    else return false;
}
void krus()
{
    int c = 0;
    sort(e,e+cnt,cmp);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if(i==j) mp2[i][j] = 0;
            else mp2[i][j] = INF;
        }
    }
    for(int i=0;i<cnt;i++)
    {
        if(merge(e[i].u,e[i].v))
        {
            ans[c].u = e[i].u;
            ans[c].v = e[i].v;
            ans[c++].w = e[i].w;
            int ta = e[i].u,tb = e[i].v,tc = e[i].w;
            mp2[ta][tb] = mp2[tb][ta] = tc;
        }
        if(c==n-1) break;
    }
    for(int k=1;k<=n;k++)
    {
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(mp2[i][k]==INF) break;
                mp2[i][j] = min(mp2[i][j],mp2[i][k]+mp2[k][j]);
            }
        }
    }
    int ok = 0;
    for(int i=n-2;i<cnt;i++)
    {
        int ta = e[i].u,tb = e[i].v,tc = e[i].w;
        if(mp2[ta][tb]!=tc)
        {
            ans[c].u = ta;
            ans[c].v = tb;
            ans[c++].w = tc;
        }
    }
    if(!ok)
    {
        ans[c].u = e[0].u;
        ans[c].v = e[0].v;
        ans[c++].w = e[0].w;
    }
    for(int i=0;i<n;i++)
        printf("%d %d %d\n",ans[i].u,ans[i].v,ans[i].w);
}
int main()
{
    int sign = 0;
    while(scanf("%d",&n)!=EOF)
    {
        if(!sign) sign = 1;
        else printf("\n");
        init();
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
                scanf("%d",&mp[i][j]);
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<i;j++)
            {
                add(i,j,mp[i][j]);
            }
        }
        krus();
    }
    return 0;
}
时间: 2024-10-14 14:53:57

UESTC 888 Absurdistan Roads (kruscal+floyd)的相关文章

CDOJ 888 Absurdistan Roads

Absurdistan Roads Time Limit: 5678/3456MS (Java/Others)     Memory Limit: 65432/65432KB (Java/Others) The people of Absurdistan discovered how to build roads only last year. After the discovery, every city decided to build their own road connecting t

hdu 1102 Constructing Roads Kruscal

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1102 题意:这道题实际上和hdu 1242 Rescue 非常相似,改变了输入方式之后, 本题实际上更适合用Prim来做. 用Kruscal的话要做一些变化. /*Constructing Roads Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s)

UESTC-888-Absurdistan Roads(kruskal+floyd)

The people of Absurdistan discovered how to build roads only last year. After the discovery, every city decided to build their own road connecting their city with another city. Each newly built road can be used in both directions. Absurdistan is full

UVALive 6622 Absurdistan Roads

题意: n(2000)个点的图  给出它的最短路矩阵  用n条边构造出满足最短路矩阵的图  保证图连通且解存在 思路: 我们可以先保证图连通  那么需要n-1条边  联想到是不是最小生成树?? 可以这样想  假设abc点已经连通  现在考虑再加入到连通块中一个点比如d  如果d-b的距离是d到abc三个点中最短的  那么这条边一定要被选  因为如果不选d-b  假设选了d-a  那么d-a已经长于d-b了  所以d-b的距离将不永远得不到满足 这样我们就可以根据最小生成树选出n-1条边了  还差

UVAlive 6622 Absurdistan Roads(最小生成树+LCA)

题目地址:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4633 思路:每个点之间连边,权值为两点之间的最短距离.则该图的最小生成树的n-1条边在最终的n条边内.则两点(i,j)之间距离为dist[i]+dist[j]-2*dist[ LCA(i,j) ](dist[i]表示根节点(设为1)到i节点的距离).若树上每点之间的

【kruscal】【最小生成树】bzoj2421 Constructing Roads

SB题,求最小生成树,其中有些边已经给您建好啦. 随意暴力即可. 1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 using namespace std; 5 int rank[10001],fa[10001],n,m,a[101][101],q,x,y,f1,f2,ans; 6 void init(){for(int i=1;i<=n;i++) fa[i]=i;} 7 int find

BNUOJ33566 Cycling Roads(并查集+判断两线段相交)

Cycling Roads Time Limit: 1000ms Memory Limit: 65536KB This problem will be judged on Ural. Original ID: 1966 64-bit integer IO format: %lld      Java class name: (Any) Prev Submit Status Statistics Discuss Next Font Size:  +   - Type:   None Graph T

Dark roads(kruskal)

Dark roads Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Submission(s) : 7   Accepted Submission(s) : 2 Problem Description Economic times these days are tough, even in Byteland. To reduce the operating costs,

POJ 1734 Sightseeing trip (Floyd 最小环+记录路径)

Sightseeing trip Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5040   Accepted: 1932   Special Judge Description There is a travel agency in Adelton town on Zanzibar island. It has decided to offer its clients, besides many other attra