您的位置:首页 > 其它

HDU 2433 Travel 枚举+最短路

2015-10-23 15:48 495 查看
题意:有1~N个点,有M条边,无向图,sum=(每个点到其它个点的最短路程的总和),问你当删除M条边的i-th边时,sum=?



想法:两个步骤:1.先求出最开始的sum;2.求出删的那条边e(u,v),u到v的最短距离,newsum=sum-2+2*dis[u->v]。



#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#define inf 0x7fffffff
using namespace std;
const int nodes=100+5;
const int edges=3000+5;
int n,m;
int sum;
struct edge
{
int u,v;
}par[edges];
struct node
{
int u,v,next;
}e[edges*2];
int head[nodes],cnt;
void Init()
{
memset(head,-1,sizeof(head));
cnt=0;
}
void add(int a,int b)
{
e[cnt].u=a;
e[cnt].v=b;
e[cnt].next=head[a];
head[a]=cnt++;
}
int spfa(int s,int t,int liu,int liv)
{
int mark=1;
int dis[nodes],vis[nodes];
queue<int>q;
while(!q.empty()) q.pop();
for(int i=1;i<=n;i++)
{
dis[i]=inf;
vis[i]=0;
}
dis[s]=0;
vis[s]=1;
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=0;
for(int i=head[u];i+1;i=e[i].next)
{
int v=e[i].v;
if(e[i].u==liu&&e[i].v==liv&&mark)
{
mark=0;
continue;
}
if(dis[v]>dis[u]+1)
{
dis[v]=dis[u]+1;
if(!vis[v])
{
vis[v]=1;
q.push(v);
}
}
}
}
if(liu!=-1) return dis[t];
int tot=0;
for(int i=1;i<=n;i++)
{
if(i==s) continue;
tot+=dis[i];
}
return tot;
}
void Input()
{
for(int i=1;i<=m;i++)
{
scanf("%d%d",&par[i].u,&par[i].v);
add(par[i].u,par[i].v);
add(par[i].v,par[i].u);
}
}
void treatment()
{
sum=0;
for(int i=1;i<=n;i++)
{
sum+=spfa(i,n,-1,-1);
}
for(int i=1;i<=m;i++)
{
int res=spfa(par[i].u,par[i].v,par[i].u,par[i].v);
if(res==inf) printf("INF\n");
else printf("%d\n",sum-2+2*res);
}
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
Init();
Input();
treatment();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: