//1406ms险过。
#include <cstdio>
#include <queue>
#include <vector>
#include <cstring>
#include <iostream>
using namespace std;
const int NN=110;
const int MM=3100;
struct node{
int v,e;
node() {}
node(int _v,int _e): v(_v),e(_e) {}
};
struct Edge{
int u,v;
}e[MM];
vector<node> adj[NN];
int n,m,tot,ans,sum[NN],d[NN][NN],tmp_dis[NN];
bool intree[NN][MM],tmp_in[MM],vis[NN];
int top,bn,index,dfn[NN],low[NN],stack[NN],belong[NN];
bool instack[NN];
void tarjan(int u,int fa) //判断桥边
{
dfn[u]=low[u]=++index;
stack[++top]=u;
instack[u]=true;
int v;
for (int i=0; i<adj[u].size(); i++)
{
if (adj[u][i].e==fa) continue;
v=adj[u][i].v;
if (!dfn[v])
{
tarjan(v,adj[u][i].e);
if (low[v]<low[u]) low[u]=low[v];
}
else if (instack[v] && dfn[v]<low[u])
low[u]=dfn[v];
}
if (low[u]==dfn[u])
{
bn++;
do
{
v=stack[top--];
instack[v]=false;
belong[v]=bn;
}while (v!=u);
}
}
void bfs(int S,int dis[],bool in[],int forbid=-1) //此题的边长均为1,用bfs求最短路即可
{
int u,v,e,i;
memset(vis,0,sizeof(vis));
dis[S]=0; vis[S]=true;
queue<int> q;
q.push(S);
while (!q.empty())
{
u=q.front();
q.pop();
for (i=0; i<adj[u].size(); i++)
{
v=adj[u][i].v;
e=adj[u][i].e;
if (vis[v] || e==forbid) continue;
in[adj[u][i].e]=true;
dis[v]=dis[u]+1;
vis[v]=true;
q.push(v);
}
}
}
void pre_do()
{
int i,j;
index=top=bn=0;
for (i=1; i<=n; i++) if (!dfn[i]) tarjan(i,-1);
tot=0;
memset(intree,0,sizeof(intree));
for (i=1; i<=n; i++)
{
bfs(i,d[i],intree[i]);
sum[i]=0;
for (j=1; j<=n; j++) sum[i]+=d[i][j];
tot+=sum[i];
}
}
int main()
{
int i,j,k,u,v;
while (~scanf("%d%d",&n,&m))
{
for (i=1; i<=n; i++)
{
adj[i].clear();
dfn[i]=0;
}
for (i=1; i<=m; i++)
{
scanf("%d%d",&u,&v);
e[i].u=u; e[i].v=v;
adj[u].push_back(node(v,i));
adj[v].push_back(node(u,i));
}
pre_do();
for (i=1; i<=m; i++)
{
u=e[i].u; v=e[i].v;
if (belong[u]!=belong[v]) { puts("INF"); continue; }//桥边特判
ans=tot;
for (j=1; j<=n; j++)
{
if (!intree[j][i]) continue;
ans-=sum[j];
bfs(j,tmp_dis,tmp_in,i);
for (k=1; k<=n; k++) ans+=tmp_dis[k];
}
printf("%d\n",ans);
}
}
return 0;
}
HDOJ2433-最短路径树
最新推荐文章于 2021-05-23 12:20:04 发布