hdu2433 最短路+思维

来源:互联网 发布:淘宝上从那里定制衣服 编辑:程序博客网 时间:2024/05/29 15:08

题意:给你n个点m条双向边,边的权值为1,要你求除去第i条边后任意两点的最短路的权值的和。

思路:先求点到其他点的最短路并且把路径记录下来,如果直接除去一条边求一次任意两点的最短路那肯定超时了,如果这条边在这个点到其他点最短路路的边中,那么去掉这条边,就对原来的最短路径有影响,那么最短路径就要重新算,如果这条边不在原来的最短路径中,那么直接就跟原来的最短路是一样的,也就没必要在重新求了,加上输出即可。

然后这个图如果是不连通的,就直接输出M个INF即可。

代码:


#include<stdio.h>#include<queue>#include<vector>#include<stdlib.h>#include<string.h>using namespace std;#define INF 999999999struct edge{    int from,to;    int w;    int flag;};int n,m;int dis[120];vector<edge>edges;vector<int>G[120];int sum[120];int way[120][120];void addedge(int x,int y,int w){    edge a={x,y,1,1};    edges.push_back(a);    edge b={y,x,1,1};    edges.push_back(b);    G[y].push_back(edges.size()-1);    G[x].push_back(edges.size()-2);}bool SPFA(int x){    for(int i=1;i<=n;i++)    {        dis[i]=INF;    }    dis[x]=0;    queue<int>q;    q.push(x);    int a;    while(!q.empty())    {        a=q.front();        q.pop();        for(int i=0;i<G[a].size();i++)        {            edge v=edges[G[a][i]];            if(dis[a]+v.w<dis[v.to])            {                dis[v.to]=dis[a]+v.w;                way[x][v.to]=a;                q.push(v.to);            }        }    }    for(int i=1;i<=n;i++)    {       if(dis[i]!=INF) sum[x]=sum[x]+dis[i];        else return 0;    }    return 1;}int SPFA1(int x){    for(int i=1;i<=n;i++)    {        dis[i]=INF;    }    dis[x]=0;    queue<int>q;    q.push(x);    int a;    while(!q.empty())    {        a=q.front();        q.pop();        for(int i=0;i<G[a].size();i++)        {            edge v=edges[G[a][i]];            if(!v.flag) continue;            if(dis[a]+v.w<dis[v.to])            {                dis[v.to]=dis[a]+v.w;                q.push(v.to);            }        }    }    int ans=0;    for(int i=1;i<=n;i++)    {       if(dis[i]!=INF) ans+=dis[i];        else return 0;    }    return ans;}int solove(){   memset(sum,0,sizeof(sum));    for(int i=1;i<=n;i++)    {       if(!SPFA(i)) {          for(int i=1;i<=n;i++)          {              printf("INF\n");          }          return 1;       }    }    for(int i=0;i<edges.size();i+=2)    {    int x=edges[i].from,y=edges[i].to;         int ans=0;         int flag=1;        for(int j=1;j<=n;j++)        {            if(way[j][x]==y||way[j][y]==x)            {                edges[i].flag=0;                edges[i+1].flag=0;                int t=SPFA1(j);                if(t==0) {printf("INF\n"); edges[i].flag=1;edges[i+1].flag=1;flag=0;break;}                else ans+=t;                edges[i].flag=1;                edges[i+1].flag=1;            }            else            {                ans+=sum[j];            }        }      if(flag)     printf("%d\n",ans);    }}int main(){    while(scanf("%d %d",&n,&m)!=EOF)    {   for(int i=1;i<=n;i++)          G[i].clear();          edges.clear();        for(int i=1;i<=m;i++)        {            int x,y;            scanf("%d %d",&x,&y);            addedge(x,y,1);        }        solove();    }}


原创粉丝点击