http://47.92.197.167:5283/contest/451/problem/3
求一个特殊图最大独立团,相当于是补集的最大独立集。然后这个补集(是个偏序集)满足传递闭包性质,根据 最大独立集 = 最长反链 = 最小链覆盖,题目等价于求最小链覆盖。这个可以直接网络流跑60分的。
对于正解,有点神秘。每个点直接匹配,往最小的能匹配的匹配。然后至多 m \sqrt m m 个点未匹配( m m m 为原图边数)。这 m \sqrt m m 个点暴力匹配,然后用并查集优化(不懂)
今晚回去想一想,下次问一下小沈队,待补
#include<bits/stdc++.h>
using namespace std;
#ifdef LOCAL
#define debug(...) fprintf(stdout, ##__VA_ARGS__)
#else
#define debug(...) void(0)
#endif
#define int long long
inline int read(){int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;
ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+
(x<<3)+(ch^48);ch=getchar();}return x*f;}
#define Z(x) (x)*(x)
#define pb push_back
#define fi first
#define se second
//#define M
//#define mo
#define N 200000
int n, m, i, j, k, T;
int a[N], to[N], shu[N], f[N], vis[N], ans;
vector<int> G[N];
set<int> s;
int fa(int x) {
if(f[x] == x) return x;
return f[x] = fa(f[x]);
}
int dfs(int x) {
if(vis[x]) return 0; vis[x] = 1;
int l = 0;
for(int j = 1; j < x && j; j = fa(j + 1)) {
while(l != G[x].size() && G[x][l] < j) ++l;
// debug("Try : %lld %lld\n", x, j);
if(l == G[x].size() || G[x][l] > j) {
++f[j];
// debug("%lld -> %lld [%lld %lld]\n", x, j, shu[j], vis[shu[j]]);
if(!shu[j]) return to[x] = j, shu[j] = x, 1;
if(dfs(shu[j])) return to[x] = j, shu[j] = x, 1;
}
}
return 0;
}
signed main()
{
freopen("excavator.in", "r", stdin);
freopen("excavator.out", "w", stdout);
// srand(time(NULL));
// T=read();
// while(T--) {
//
// }
n = read(); m = read(); ans = n;
for(i = 1; i <= n; ++i) a[i] = i;
for(i = 1; i <= m; ++i) {
j = read();
swap(a[j], a[j + 1]);
G[max(a[j], a[j + 1])].pb(min(a[j], a[j + 1]));
}
for(i = 1; i <= n; ++i) sort(G[i].begin(), G[i].end());
for(i = 1; i <= n; ++i) {
int l = 0;
for(int j : s) {
while(l < G[i].size() && G[i][l] < j) ++l;
if(l == G[i].size() || G[i][l] > j) {
to[i] = j; shu[j] = i; --ans; s.erase(j);
// debug("%d -> %d ! \n", i, j);
break;
}
}
s.insert(i);
}
debug("%lld\n", ans);
for(i = 1; i <= n; ++i) {
if(to[i]) continue;
memset(vis, 0, sizeof(vis));
for(j = 1; j <= n; ++j) f[j] = j;
ans -= dfs(i);
debug("---\n");
}
printf("%lld", ans);
return 0;
}