//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; }