您的位置:首页 > 其它

HDU 2433 Travel (最短路,BFS,变形)

2015-06-30 22:08 477 查看
题意:

  给出一个图的所有边,每次从图中删除一条边,求任意点对的路径总和(求完了就将边给补回去)。(有重边)

思路:

#include <bits/stdc++.h>
using namespace std;
const int N=105, INF=0x7f7f7f7f;
int mapp

;//图矩阵
bool mapp2

;   //标记从某点出发所需关键路径
int tem_sum
;
int num
;     //每个点的度
int vis
;     //用于BFS
vector<pair<int,int> >  vect;   //m条边
int n, m;

int bfs(int x)
{
memset(vis,0,sizeof(vis));
deque<int> que(1,x);
int cnt=0, sum=0;
vis[x]=1;
while(!que.empty())
{
cnt++;
int siz=que.size();
for(int i=0; i<siz; i++)
{
int tmp=que.front();
que.pop_front();
for(int j=1; j<=n; j++)
{
if(!vis[j]&&mapp[tmp][j])
{
vis[j]=1;
sum+=cnt;
mapp2[x][tmp][j]= mapp2[x][j][tmp]=1;//主要在这,记录每个点出发所需要的关键路径
que.push_back(j);
}
}
}
}
return sum;
}

int cal(int a,int b)    //a-b是删除的边
{
int sum=0;
for(int i=1; i<=n; i++)
{
if(!a || mapp2[i][a][b] )
{
int tmp=bfs(i);
if(!tmp)    return 0;
if(!a)  tem_sum[i]=tmp; //第一次求还得更新tem_sum
sum+=tmp;
}
else    sum+=tem_sum[i];
}
return sum;
}

int main()
{
//freopen("input.txt", "r", stdin);
int a, b, c;
while(cin>>n>>m)
{
vect.clear();
memset(mapp,0,sizeof(mapp));
memset(mapp2,0,sizeof(mapp2));
memset(num,0,sizeof(num));
memset(tem_sum,0,sizeof(tem_sum));  //一旦更新,不再改

for(int i=0; i<m; i++)
{
scanf("%d%d",&a,&b);
mapp[a][b]++, mapp[b][a]++;
num[a]++, num[b]++;
vect.push_back(make_pair(a,b));
}

int sum=cal(0,0);    //先求sum,看能否每点互通,不通以下都不必计算了。
for(int i=0; i<m; i++)
{
a=vect[i].first,  b=vect[i].second;
if(num[a]==1 || num[b]==1 || m<n || sum==0 )   //度为1的点,边不够,不连通
{
printf("INF\n");
continue;
}
if(mapp[a][b]==1)                   //仅有那么1条边,才需要更新
{
mapp[a][b]--, mapp[b][a]--;     //先断开
int ans=cal(a,b);//只求需要该边的SSSP
if(ans==0)  printf("INF\n");
else        printf("%d\n",ans);
mapp[a][b]++, mapp[b][a]++;     //再连上
}
else    printf("%d\n",sum);         //非关键,直接输出
}

}
return 0;
}


AC代码(BFS)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: