最小距离之和 CODEVS

来源:互联网 发布:真人快打x没有网络链接 编辑:程序博客网 时间:2024/06/06 23:57

点击打开链接

floyd变形 每次破坏一条边 问破坏这条边后所有国家距离之和

如果按照题目所给顺序求解 感觉每次都要跑一遍floyd n^4肯定TLE

但是逆序考虑 每次增边 然后松弛就好办了

floyd板子就是挑当前一个点 k 看其他两点 i j 能否通过 k 来进行松弛 这里就是把点换成边而已

#include <bits/stdc++.h>using namespace std;#define N 0x3f3f3f3f3f3f3f3f#define ll long longll e[210][210];ll ans[210];int u[210],v[210],w[210];int n,q;void floyd();void calculate();int main(){    int i,j;    while(scanf("%d",&n)!=EOF)    {        for(i=1;i<=n;i++)        {            for(j=1;j<=n;j++)            {                scanf("%lld",&e[i][j]);            }        }        scanf("%d",&q);        for(i=1;i<=q;i++)        {            scanf("%d%d",&u[i],&v[i]);            w[i]=e[u[i]][v[i]];            e[u[i]][v[i]]=N;        }        floyd();        calculate();        for(i=1;i<=q;i++)        {            if(ans[i]!=N) printf("%lld\n",ans[i]);            else printf("INF\n");        }    }    return 0;}void floyd(){    ll sum;    int i,j,k,flag;    for(k=1;k<=n;k++)    {        for(i=1;i<=n;i++)        {            for(j=1;j<=n;j++)            {                if(e[i][j]>e[i][k]+e[k][j])                {                    e[i][j]=e[i][k]+e[k][j];                }            }        }    }    sum=0,flag=0;    for(i=1;i<=n;i++)    {        for(j=1;j<=n;j++)        {            if(e[i][j]==N)            {                flag=1;                break;            }            sum+=e[i][j];        }        if(flag==1) break;    }    if(flag==1) ans[q]=N;    else ans[q]=sum;    return;}void calculate(){    ll sum;    int k,i,j,flag;    for(k=q;k>=2;k--)    {        for(i=1;i<=n;i++)        {            for(j=1;j<=n;j++)            {                if(e[i][j]>e[i][u[k]]+w[k]+e[v[k]][j])                {                    e[i][j]=e[i][u[k]]+w[k]+e[v[k]][j];                }            }        }        sum=0,flag=0;        for(i=1;i<=n;i++)        {            for(j=1;j<=n;j++)            {                if(e[i][j]==N)                {                    flag=1;                    break;                }                sum+=e[i][j];            }            if(flag==1) break;        }        if(flag==1) ans[k-1]=N;        else ans[k-1]=sum;    }    return;}


原创粉丝点击