[Luogu 1640] SCOI2010 連續攻擊遊戲
阿新 • • 發佈:2018-01-15
con 輸出 ges clu using std code size oid
[Luogu 1640] SCOI2010 連續攻擊遊戲
<題目鏈接>
DP太惡心,回來二分圖這邊放松一下心智。
這個建圖真的是難以想到。
因為要遞增啊,屬性值放x部,裝備放y部,對應連邊跑Hungary就好了。
註意如果中間有點匹配不到了就要直接停止,輸出答案(因為無法做到連續遞增了)。
就這樣。頹廢產物。
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN=1010010,MAXM=2000010;
bool vis[MAXN];
int n,m,cnt,ans,head[MAXN],match[MAXN];
struct edge
{
int nxt,to;
}e[MAXM];
void AddEdge(int u,int v)
{
e[++cnt].nxt=head[u];
e[cnt].to=v;
head[u]=cnt;
}
void AddEdges(int x,int y,int v)
{
AddEdge(x,v),AddEdge(y,v);
}
int max3(int a,int b,int c)
{
return max(max(a,b),c);
}
bool DFS(int u)
{
for(int i=head[u],v;i;i=e[i].nxt)
if(!vis[v=e[i].to])
{
vis[v]=1;
if(!match[v] || DFS(match[v]))
{
match[u]=v,match[v]=u;
return 1;
}
}
return 0;
}
void Hungary(void)
{
for(int i=1 ;i<=m;++i)
if(!match[i])
{
memset(vis,0,sizeof vis);
if(DFS(i))
++ans;
else
break;
}
printf("%d\n",ans);
}
int main(int argc,char *argv[])
{
scanf("%d",&n);
for(int i=1,x,y;i<=n;++i)
{
scanf("%d %d",&x,&y);
AddEdges(x,y,i+10000);
m=max3(m,x,y);
}
Hungary();
return 0;
}
謝謝閱讀。
[Luogu 1640] SCOI2010 連續攻擊遊戲