The King’s Problem

Cities and there are n and m have the channel. If a road has come from a city there is no way to go, then this city's first all the way into a country, each city can only belong to a country, a city on the ring of course, belong to the same country. Q. How many of these cities are divided into at least two countries.

Because the presence of the drawing ring, and in the bipartite graph is a directed acyclic graph when correctly, so the first point with a strong deflation even reconstituted directed acyclic graph. Then bipartite matching.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<vector>
#define INF 0x3f3f3f3f
using namespace std;
const int N=10005;
vector<int> g[N];
stack<int> q;
int n,m,dfs_clock,scc_cnt;
int dfn[N],low[N],sccno[N],link[N];
bool vis[N],map[N][N];
void Init()         
{
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(sccno,0,sizeof(sccno));
    memset(map,false,sizeof(map)); 
    dfs_clock=scc_cnt=0;
    for(int i=0;i<=n;i++)
      g[i].clear();
    while(!q.empty())
      q.pop();
}
void tarjan(int u)       
{
    dfn[u]=low[u]=++dfs_clock;
    q.push(u);
    for(int i=0;i<g[u].size();i++)
    {
        int v=g[u][i];
        if(!dfn[v])
        {
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(!sccno[v])
          low[u]=min(low[u],dfn[v]);
    } 
    if(low[u]==dfn[u])
    {
        scc_cnt++;
        while(!q.empty())
        {
            int v=q.top();
            q.pop();
            sccno[v]=scc_cnt;
            if(v==u)
              break;
        } 
    }
} 
bool dfs(int u)     
{
    for(int i=1;i<=n;i++)
    {
        if(!vis[i]&&map[u][i])
        {
            vis[i]=true;
            if(!link[i]||dfs(link[i]))
            {
                link[i]=u;
                return true;
            }
        }
    }
    return false;
}
int hungary()         
{
    int ans=0;
    memset(link,0,sizeof(link));
    for(int i=1;i<=n;i++)
    {
        memset(vis,false,sizeof(vis));
        if(dfs(i))
          ans++;
    }
    return scc_cnt-ans;
}
int main()
{
    int t,u,v;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        Init();
        while(m--)
        {
            scanf("%d%d",&u,&v);
            g[u].push_back(v);
        }
        for(int i=1;i<=n;i++)
          if(!dfn[i])
            tarjan(i);
        for(int u=1;u<=n;u++)          
          for(int i=0;i<g[u].size();i++)
          {
              int v=g[u][i];
              if(sccno[u]!=sccno[v])
                map[sccno[u]][sccno[v]]=1;
          } 
        printf("%d\n",hungary());
    }
    return 0;
}
Published 44 original articles · won praise 35 · views 765

Guess you like

Origin blog.csdn.net/huangziguang/article/details/104482839