有n个装备,每个装备都可以选择一种属性值(1<=ai<=10000),每种装备只能选择一种属性值,只能攻击一次,造成伤害等于属性值。你要从1开始造成伤害,造成的伤害每次+1,求最多能造成多少伤害。 n<=1000000
题解:二分图匹配,直接上匈牙利就好啦。注意要先走小的那一侧,复杂度才靠谱。
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #define MN 1010000 #define MM 10000 using namespace std; 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 * 10 + ch - '0';ch = getchar();} return x * f; } struct edge{int to,next;}e[MN*5]; int n,m,now; int mark[MN+5],cnt=0,head[MN+5],mat[MN+5]; inline void ins(int f,int t){e[++cnt]=(edge){t,head[f]};head[f]=cnt; } bool dfs(int x) { mark[x]=now; for(int i=head[x];i;i=e[i].next) if(mark[e[i].to]!=now) { mark[e[i].to]=now; if(!mat[e[i].to]||dfs(mat[e[i].to])) return mat[e[i].to]=x,mat[x]=e[i].to,true; } return false; } int main() { n=read(); for(int i=1;i<=n;i++) { int x=read(),y=read(); ins(x,i+MM);ins(y,i+MM); } for(now=1;now<=10000;now++) if(!dfs(now)) return 0*printf("%d ",now-1); puts("10000"); return 0; }