CF400D最短路

來源:互聯網
上載者:User

標籤:blog   os   io   for   div   line   amp   log   

題意:給你n個點,是否可以分成k塊,如果可以分,就求任意兩塊之間的最短路。如果兩點距離為0即為一塊,但是還有一個條件,我一開始沒看清,

以為只要是可以滿足K塊就行,與先後順序無關,其實不然。如果是分成3塊,第一塊是5,第二塊是3,第三塊是4,那麼1到5號點都是第一塊的,

6到8號點時第二塊的,9到11號點是第三塊的,如果不滿足這種就是錯誤的。有點坑啊,英語是硬傷啊!!!!!

思路:先用並查集如果滿足w=0;那麼就是一個集合,再按順序求出那些點應該是在那個塊。再求塊到塊之間如果有路徑,就儲存最短的那條,

判斷是不是都滿足分塊的要求,如果滿足,就跑一次Floyd,求得任意兩塊之間的距離。

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxm = 100009;const int maxn = 600;const int inf = 1<<29;struct node{int u,v,w;}eg[maxm];int fa[maxm];int dis[maxn][maxn];int Count[maxn]; int hash[maxn];int sum[maxn];int n,m,k;int pre[maxm];void init(){int i,j;for(i=0; i<= n; i++) fa[i] = -1;for(i =0;i<maxn;i++){for(j=0;j<maxn;j++)dis[i][j] = inf;dis[i][i] = 0;}}int find(int x){int p;for(p =x;fa[p] >= 0;p  = fa[p]);while(x != p){int temp = fa[x];fa[x] = p;x = temp;}return p;}void Union(int a,int b){int x = find(a);int y = find(b);if(x == y) return ;int temp = fa[x] + fa[y];if(fa[x] > fa[y])fa[x] = y, fa[y] = temp;elsefa[y] = x, fa[x] = temp;}void floyd(){for(int z =0; z < k; z++){for(int i= 0; i < k; i++){for(int j = 0;j < k; j++){if(dis[i][j] > dis[i][z] + dis[z][j])dis[i][j] = dis[i][z] + dis[z][j];}}}}inline int min(int a,int b){return a < b ? a : b;}int main(){int i;while(~scanf("%d%d%d",&n,&m,&k)){init();sum[0] = 0;for(i=1;i<=k;i++){scanf("%d",&Count[i]);sum[i] =sum[i-1] + Count[i];}for(i=0;i<m;i++){scanf("%d%d%d",&eg[i].u,&eg[i].v,&eg[i].w);if(eg[i].w == 0)Union(eg[i].u,eg[i].v);int u=lower_bound(sum+1,sum+k+1,eg[i].u)-sum;u--;            int v=lower_bound(sum+1,sum+k+1,eg[i].v)-sum;v--;if(u == v)continue;dis[u][v] = dis[v][u] = min(dis[u][v],eg[i].w);}    memset(pre,0,sizeof(pre));        int flag=1;        for(i=1;i<=n;i++)        {            int posu=lower_bound(sum+1,sum+k+1,i)-sum;            int u=find(i);            if(pre[posu])            {                if(u!=pre[posu])                {                    flag=0;                    break ;                }            }            else            {                pre[posu]=u;            }        }        if(flag) printf("Yes\n");        else        {            printf("No\n");            continue ;        }floyd();for(i=0;i<k;i++){for(int j=0; j < k;j++){if(dis[i][j] >= inf)dis[i][j] = -1;printf("%d ",dis[i][j]);}printf("\n");}}return 0;}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.