HDOJ2433-最短路径树

来源:互联网 发布:mac vi 强制保存 编辑:程序博客网 时间:2024/06/06 11:12
//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;}