1. 程式人生 > >【51nod】1164 最高的獎勵 V2

【51nod】1164 最高的獎勵 V2

LV out for ace pac define ifdef || std

題解

一道比較神奇的二分圖匹配

既然有n個元素,那麽能匹配n個位置,我們把這n個位置找出來,是每個區間從左端點開始找到一個沒有被匹配到的位置作為該點(我們忽略右端點)

然後我們從價值大到小,然後從左端點的位置開始匹配,如果這個點沒有被匹配,就匹配這個點
否則如果這個點已經匹配的區間右端點大於該點的右端點,就用matk[y]去匹配y + 1,否則就用x取匹配y + 1

代碼

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <set> #include <cmath> #include <bitset> #include <queue> #define enter putchar(‘\n‘) #define space putchar(‘ ‘) //#define ivorysi #define pb push_back #define mo 974711 #define pii pair<int,int> #define mp make_pair #define fi first #define se second #define MAXN 500005
#define eps 1e-12 using namespace std; typedef long long int64; typedef double db; template<class T> void read(T &res) { res = 0;char c = getchar();T f = 1; while(c < ‘0‘ || c > ‘9‘) { if(c == ‘-‘) f = -1; c = getchar(); } while(c >= ‘0‘ && c <= ‘9‘
) { res = res * 10 - ‘0‘ + c; c = getchar(); } res = res * f; } template<class T> void out(T x) { if(x < 0) {x = -x;putchar(‘-‘);} if(x >= 10) out(x / 10); putchar(‘0‘ + x % 10); } int N,pos[5005]; int matk[5005]; struct Seg { int s,t;int64 w; }S[5005]; bool cmpw(Seg a,Seg b) { return a.w > b.w; } bool cmps(Seg a,Seg b) { return a.s < b.s; } bool match(int x,int y) { if(y > N || pos[y] > S[x].t) return 0; if(!matk[y]) {matk[y] = x;return 1;} if(S[matk[y]].t <= S[x].t) { if(match(x,y + 1)) { matk[y] = x; return 1; } } else { if(match(matk[y],y + 1)) { matk[y] = x; return 1; } } return 0; } void Solve() { read(N); int s,t;int64 w; for(int i = 1 ; i <= N ; ++i) { read(s);read(t);read(w); S[i] = (Seg){s,t,w}; } sort(S + 1,S + N + 1,cmps); for(int i = 1 ; i <= N ; ++i) { if(pos[i - 1] < S[i].s) pos[i] = S[i].s; else pos[i] = pos[i - 1] + 1; } sort(S + 1,S + N + 1,cmpw); int64 ans = 0; for(int i = 1 ; i <= N ; ++i) { int t = lower_bound(pos + 1,pos + N + 1,S[i].s) - pos; if(match(i,t)) ans += S[i].w; } out(ans);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); }

【51nod】1164 最高的獎勵 V2