标签:each bug mat ref cst divide training int scan
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
题意:给你n个点,m条边,可以将一个单联通分量缩成一个点,最少能分成几个点;
思路:先将强连通分量缩点,强连通肯定是可以合并成一个点,然后求无环DAG图的最小路径覆盖即可;
#include<iostream> #include<cstdio> #pragma comment(linker, "/STACK:1024000000,1024000000") #include<iostream> #include<cstdio> #include<cmath> #include<string> #include<queue> #include<algorithm> #include<stack> #include<cstring> #include<vector> #include<list> #include<set> #include<map> #include<bitset> using namespace std; #define LL unsigned long long #define pi (4*atan(1.0)) #define eps 1e-4 #define bug(x) cout<<"bug"<<x<<endl; const int N=5e3+10,M=1e5+10,inf=1e9+10; const LL INF=1e18+10,mod=2147493647; struct is { int u,v; int next; }edge[M]; int head[N]; int belong[N]; int dfn[N]; int low[N]; int stackk[N<<1]; int instack[N]; int number[N]; int n,m,jiedge,lu,bel,top; void update(int u,int v) { jiedge++; edge[jiedge].u=u; edge[jiedge].v=v; edge[jiedge].next=head[u]; head[u]=jiedge; } void dfs(int x) { dfn[x]=low[x]=++lu; stackk[++top]=x; instack[x]=1; for(int i=head[x];i;i=edge[i].next) { if(!dfn[edge[i].v]) { dfs(edge[i].v); low[x]=min(low[x],low[edge[i].v]); } else if(instack[edge[i].v]) low[x]=min(low[x],dfn[edge[i].v]); } if(low[x]==dfn[x]) { int sum=0; bel++; int ne; do { sum++; ne=stackk[top--]; belong[ne]=bel; instack[ne]=0; }while(x!=ne); number[bel]=sum; } } void tarjan() { memset(dfn,0,sizeof(dfn)); bel=lu=top=0; for(int i=1;i<=n;i++) if(!dfn[i]) dfs(i); } void init() { memset(head,0,sizeof(head)); jiedge=0; } vector<int> g[N]; int cy[N]; bool vis[N]; bool dfs1(int u){ for(int i=0; i<g[u].size(); ++i){ int v = g[u][i]; if(vis[v]) continue; vis[v] = true; if(cy[v]==-1 || dfs1(cy[v])){ cy[v] = u; return true; } } return false; } int solve(int n){ int ret = 0; memset(cy, -1, sizeof(cy)); for(int i=1;i<=n;++i){ memset(vis, 0, sizeof(vis)); ret += dfs1(i); } return n - ret; } int main() { int T; scanf("%d",&T); while(T--) { init(); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) g[i].clear(); for(int i=1;i<=m;i++) { int u,v; scanf("%d%d",&u,&v); update(u,v); } tarjan(); for(int i=1;i<=jiedge;i++) { if(belong[edge[i].v]!=belong[edge[i].u]) { g[belong[edge[i].u]].push_back(belong[edge[i].v]); } } int ans=solve(bel); printf("%d\n",ans); } return 0; }
hdu 3861 The King’s Problem trajan缩点+二分图匹配
标签:each bug mat ref cst divide training int scan
原文地址:http://www.cnblogs.com/jhz033/p/7106907.html