九度 oj 题目1100:最短路径

62 篇文章 0 订阅
9 篇文章 0 订阅

http://ac.jobdu.com/problem.php?pid=1100


参考了http://blog.csdn.net/thudaliangrx/article/details/49357075


因为每条新边比之前所有边的和都要长,所以只要是当前边能联通的点对,点对当前的距离就是最短距离


#include <stdio.h>

static int folk[102];
static int d[102][102];
static int rank[102];

int find(int u){ 
    return u == folk[u] ? u : folk[u] = find(folk[u]); 
} 

void unionSet(int a,int b){ 
    int x = find(a);  
    int y = find(b); 
    if(x == y) return; 
    if(rank[x] >= rank[y]){ 
        rank[x] += rank[y]; 
        folk[y] = x;
    }else{ 
        rank[y] += rank[x]; 
        folk[x] = y;
    }   
} 

int mod (int n,int k){ 
    int res = 1;
    for (int i = 0; i < k; ++i) { 
        res *=n; 
        res %=100000;
    }  
    return res;
} 

int main(){ 
   //freopen("in/1100.in","r",stdin); 
   //freopen("out/1100.tree.out","w",stdout); 
   int n,m,a,b; 
   while(scanf("%d %d",&n,&m) !=EOF ){ 
       for (int i = 0; i < n; ++i) { 
           folk[i] = i; 
           d[i][i] = 0;
           rank[i] = 1;
       } 
       for (int i = 0; i < m; ++i) { 
           scanf("%d %d",&a,&b);  
           int dist = mod(2,i);

           int x = find(a);
           int y = find(b);
           if(x == y) continue; 
           for (int j = 0; j < n; ++j) { 
              if( x != find(j)) continue; 
              for (int k = 0; k < n; ++k) { 
                  if( y != find(k) ) continue;  
                  d[j][k] = d[k][j] = (d[j][a] + dist + d[b][k] )%100000;
              } 
           } 
           //unionSet(x,y); 
           folk[y] = x;
       }  
       
       int root = find(0);
       for (int i = 1; i < n; ++i) { 
           if(root != find(i) ) printf("-1\n");   
           else{ 
               printf("%d\n",d[0][i]);  
           } 
       } 
   }  
}  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值