The shortest path and check the set/obtain the shortest path using the edge property.

Source: Internet
Author: User

N cities, ranging from 0 to N-1, M roads, K roads (K starting from 0) are 2 ^ K, returns the shortest distance from a city numbered 0 to another city.

Input: the first line is two positive integers, N (2 <= n <= 100) m (M <= 500), indicating that there are n cities and M roads.

The next two integers in the M line indicate the numbers of the two connected cities. The input data must have no duplicate edges.
Output: N-1 line, indicating the shortest circuit from city 0 to other cities. If not, output-1. The value is too large to output with Mod 100000.

Ideas:
Because the weight of edge I w [I] = 2 ^ I, then the sum of the weight of the edge of the front I-1 is W [0] + W [1] + · + W [I-1] = (2 ^ I)-1
That is to say, the sum of the weights of the first I-1 edge is smaller than that of the first I side.
Based on this nature, when an I-th edge (A, B) is added:

If A and B are not connected, the shortest path between A and B is W [I].

If A and B are connected, the shortest paths between A and B remain unchanged.

#include<cstdio>#include<fstream>using namespace std;#define MAX 550#define INF 9999999#define M 100000int father[MAX], rank[MAX];int d[MAX][MAX];void init ( int n ){    for ( int i = 0; i < n; i++ )    {        father[i] = i;        rank[i] = 1;        d[i][i] = 0;    }}int Find ( int i ){    if ( i != father[i] )        father[i] = Find(father[i]);    return father[i];}void Union ( int a, int b ){    int ta = Find(a);    int tb = Find(b);    if ( ta == tb ) return;    if ( rank[a] >= rank[b] )    {        father[tb] = ta;        rank[ta] += rank[tb];    }    else    {        father[ta] = tb;        rank[tb] += rank[ta];    }}int mod_exp ( long long a, long long b ){    long long ret = 1;    while ( b > 0 )    {        if ( b & 1 )            ret = ( ret * a ) % M;        b >>= 1;        a = ( a * a ) % M;    }    return ret;}int main(){    int n, m, i, j, k;    int a, b, ta, tb, dist;    while ( scanf("%d%d",&n,&m) != EOF )    {        init(n);        for ( k = 0; k < m; k++ )        {            scanf("%d%d",&a,&b);            ta = Find(a);            tb = Find(b);            if ( ta == tb ) continue;            dist = mod_exp(2,k);            for ( i = 0; i < n; i++ )            {                if ( Find(i) != ta ) continue;                for ( j = 0; j < n; j++ )                {                    if ( Find(j) != tb ) continue;                    d[i][j] = (d[i][a] + dist + d[b][j]) % M;                    d[j][i] = d[i][j];                }            }            Union(a,b);        }        ta = Find(0);        for ( i = 1; i < n; i++ )        {            if ( Find(i) == ta )                printf("%d\n",d[0][i]);            else printf("-1\n");        }    }    return 0;}

 

Of course, the shortest path can still be obtained using a standard algorithm ···

# Include <cstdio> # include <cstring> # include <algorithm> using namespace STD; # define M 100000 # define INF 1999999 class node {public: int DN [505]; void Init (INT); bool operator <(const node &); bool operator = (const node &); node operator + (const node &); node operator + (INT) ;}; void node: Init (INT flag) {for (INT I = 500; I> = 0; I --) DN [I] = flag? INF: 0;} bool node: Operator <(const node & X) {for (INT I = 500; I> = 1; I --) if (DN [I] <X. DN [I]) return true; else if (DN [I]> X. DN [I]) return false;} bool node: Operator = (const node & X) {for (INT I = 500; I> = 1; I --) if (DN [I]! = X. DN [I]) return false; return true;} node: Operator + (const node & X) {node ret; For (INT I = 500; I> = 1; I --) ret. DN [I] = DN [I] + X. DN [I]; return ret;} node: Operator + (INT X) {node ret = * This; ret. DN [x] ++; return ret;} int map [110] [110], vis [110]; node D [110], mm; void Dijkstra (int n) {node TMP; int I, j, k; for (I = 1; I <= N; I ++) d [I]. init (1), vis [I] = 0; d [1]. init (0); (I = 1; I <= N; I ++) {for (TMP = mm, j = 1; j <= N; j ++) if (! Vis [J] & D [J] <TMP) TMP = d [k = J]; If (TMP = mm) break; vis [k] = 1; for (j = 1; j <= N; j ++) {If (vis [J] | map [k] [J] = inf) continue; TMP = d [k] + map [k] [J]; If (TMP <D [J]) d [J] = TMP ;}}} int mod_exp (long a, long B) {long ret = 1; while (B> 0) {If (B & 1) ret = (Ret *) % m; B> = 1; A = (A * A) % m;} return ret;} int CAL (const node & X) {int sum = 0; fo R (INT I = 1; I <= 500; I ++) {If (X. DN [I] = 0) continue; sum + = x. DN [I] % m * mod_exp (2, I-1); sum % = m;} return sum;} int main () {mm. init (1); int n, m, a, B, I, j; while (scanf ("% d", & N, & M )! = EOF) {for (I = 1; I <= N; I ++) for (j = 1; j <= N; j ++) map [I] [J] = (I = J )? 0: INF; for (I = 1; I <= m; I ++) {scanf ("% d", & A, & B); A ++; B ++; // note that the side is + 1, point + 1. of course, if this is not the case, you can also · map [a] [B] = map [B] [a] = I;} Dijkstra (n); for (I = 2; I <= N; I ++) {If (d [I] = mm) printf ("-1 \ n"); else printf ("% d \ n ", cal (d [I]) ;}} 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.