The King’s Problem
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 3156 Accepted Submission(s): 1111
Now the king asks for your help, he wants to know the least number of states he have to divide the kingdom into.
The first line for each case contains two integers n, m(0 < n <= 5000,0 <= m <= 100000), the number of cities and roads in the kingdom. The next m lines each contains two integers u and v (1 <= u, v <= n), indicating that there is a road going from city u to city v.
2.同一個州中任意兩個城市u,v要滿足,要麼u能到達v,要麼v能到達u
3.一個城市只能被劃分到一個州
#include<stdio.h>
#include<string.h>
#include<vector>
#include<stack>
#include<algorithm>
using namespace std;
const int maxn=5050;
vector<int>v[maxn];
vector<int>g[maxn];
stack<int>S;
int dfn[maxn],low[maxn];
int viss[maxn];
int marry[maxn],vis[maxn];
int index,cnt;
void init(int n)
{
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(viss,0,sizeof(viss));
for(int i=0;i<=n;i++)
v[i].clear();
index=0,cnt=0;
}
void tarjan(int x)
{
dfn[x]=low[x]=++index;
S.push(x);
for(int i=0;i<v[x].size();i++)
{
int y=v[x][i];
if(!dfn[y])
{
tarjan(y);
low[x]=min(low[x],low[y]);
}
else if(!viss[y])
{
low[x]=min(low[x],dfn[y]);
}
}
if(dfn[x]==low[x])
{
cnt++;
while(1)
{
int y=S.top();S.pop();
viss[y]=cnt;
if(y==x)
break;
}
}
}
void solve(int n)
{
for(int i=1;i<=n;i++)
{
if(!dfn[i])
tarjan(i);
}
}
bool dfs(int u)
{
for(int i=0;i<g[u].size();i++)
{
int s=g[u][i];
if(!vis[s])
{
vis[s]=1;
if(!marry[s]||dfs(marry[s]))
{
marry[s]=u;
return true;
}
}
}
return false;
}
int hungry()
{
memset(marry,0,sizeof(marry));
int ans=0;
for(int i=1;i<=cnt;i++)
{
memset(vis,0,sizeof(vis));
if(dfs(i))
ans++;
}
return ans;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,m;
scanf("%d%d",&n,&m);
init(n);
for(int i=0;i<m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
v[a].push_back(b);
}
solve(n);
for(int i=0;i<=cnt;i++)
g[i].clear();
for(int i=1;i<=n;i++)
{
for(int j=0;j<v[i].size();j++)
{
int y=v[i][j];
if(viss[i]!=viss[y])
g[viss[i]].push_back(viss[y]);
}
}
printf("%d\n",cnt-hungry());
}
}