1. 程式人生 > >[Luogu 1640] SCOI2010 連續攻擊遊戲

[Luogu 1640] SCOI2010 連續攻擊遊戲

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 連續攻擊遊戲