原本是打算用GYM-102458A做例子的.但是这个可(gai)爱(si)的题竟然如此难搞.
所以就灰溜溜的用poj-3041做例子了,(尽管这个题并不需要离散)
poj-3041和GYM-102458A一样,都需要把横坐标和纵坐标当成二部图的两边然后跑匈牙利(这就是图论的神奇之处了,风马牛不相及的两个题意,构图方法确实一样的)
这里贴上以前记得二部图的性质吧(免得我这个脑子犯浑,又忘了…)
最小点覆盖=最大匹配
最小路径覆盖=点数-最大匹配
最大独立集=点数-最大匹配
这里GYM-102458A求的是最大匹配
poj-3041求得是最小点覆盖
下面是匈牙利的板子,因为已经很熟悉了,就不多赘述了,有问题再看看以前的笔记就好 (其实是因为我太懒了)
匈牙利板子:
bool dfs(int now)
{
for (int i = head[now]; i != -1; i = edge[i].nxt)
{
int v = edge[i].to;
if (!vis[v])
{
vis[v] = 1;
if (link[v] == -1 || dfs(link[v]))
{
link[v]=now;
return 1;
}
}
}
return 0;
}
void getans()
{
int ans = 0;
for (int i = 1; i <= mx; i++)
{
memset(vis, 0, sizeof(vis));
if (dfs(i))ans++;
}
cout << ans;
}
下面着重总结一下离散的板子,以前总是觉得简单,没放在心上,结果自己一写,总是各种麻烦…终于觉得有必要总结一下,为以后省点事吧…
方法1: 包含重复元素,并且相同元素离散化后也要相同
int n;
int s[Max_n],t[Max_n];
for(int i=1;i<=n;i++){
scanf("%d",&s[i]);
t[i]=s[i];
}
sort(t+1,t+n+1);
int m=unique(t+1,t+n+1)-t-1; //m为不重复元素的个数
for(int i=1;i<=n;i++){
s[i]=lower_bound(t+1,t+m+1,s[i])-t;
}
方法2: 不管是否含有重复元素,元素离散化后各不相同。
int n;
struct node{
int x,id;
operator<(const node& no)const{
if(x!=no.x)
return x<no.x;
else
return id<no.id;
}
}no[Max_n];
int s[Max_n];
for(int i=1;i<=n;i++){
scanf("%d",&no[i].x);
no[i].id=i;
}
sort(no+1,no+n+1);
for(int i=1;i<=n;i++)s[no[i].id]=i;
嘛…原博主码风我挺喜欢的,就借用啦
最后在吐槽一波神(sha)奇(que)的GYM-102458A