這道題原來是網路流……
感覺我網路流水平不行……
這種只有兩種選擇的可以源點向該點連一條容量為b的邊,該點向匯點連一條容量為w的邊,如果割掉了b證明選w,如果割掉了w證明選b
那麼\(p\)的限制怎麼加呢,新建乙個點\(i'\),然後\(i\)往\(i'\)流一條容量為\(p\)的邊
\(i'\)再向所有不合法的\(j\)連一條容量為正無窮的邊,這樣如果\(i\)選了\(b\),\(j\)選了\(w\),會有水流從\(i\rightarrow i' \rightarrow j\)
由於\(n^2\)的邊太多了,我們用可持久化線段樹優化建圖可以改成\(o(n \log n)\)
最後的答案是每個點黑白價值的和減去最大流
#include #define fi first
#define se second
#define pii pair#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define ba 47
#define maxn 200005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
templatevoid read(t &res)
while(c >= '0' && c <= '9')
res *= f;
}templatevoid out(t x)
if(x >= 10)
putchar('0' + x % 10);
}struct node e[maxn * 10];
int head[maxn],sume = 1;
int n,s,t;
int dis[maxn],ncnt,cur[maxn];
int a[5005],b[5005],w[5005],l[5005],r[5005],p[5005];
int val[5005],tot;
queueq;
void add(int u,int v,int c)
void addtwo(int u,int v,int c)
bool bfs()
} }
return false;
}int dfs(int u,int aug)
} }
return 0;
}int dinic()
return res;
}int lc[maxn],rc[maxn],rt[5005],nw;
void insert(int x,int &y,int l,int r,int pos,int v)
int mid = (l + r) >> 1;
if(pos <= mid)
else
}void adde(int y,int l,int r,int ql,int qr)
int mid = (l + r) >> 1;
if(qr <= mid) adde(lc[y],l,mid,ql,qr);
else if(ql > mid) adde(rc[y],mid + 1,r,ql,qr);
else
}void solve()
sort(val + 1,val + tot + 1);
tot = unique(val + 1,val + tot + 1) - val - 1;
for(int i = 1 ; i <= n ; ++i)
res -= dinic();
out(res);enter;
}int main()
51nod 貪心入門
有若干個活動,第i個開始時間和結束時間是 si,fi 活動之間不能交疊,要把活動都安排完,至少需要幾個教室?分析 能否按照之一問題的解法,每個教室安排盡可能多的活動,即按結束時間排序,再貪心選擇不衝突的活動,安排乙個教室之後,剩餘的活動再分配乙個教室,繼續貪心選擇 反例 a 1,2 b 1,4 c ...
51nod 迷宮問題
1459 迷宮遊戲 基準時間限制 1 秒 空間限制 131072 kb 分值 0 難度 基礎題 你來到乙個迷宮前。該迷宮由若干個房間組成,每個房間都有乙個得分,第一次進入這個房間,你就可以得到這個分數。還有若干雙向道路鏈結這些房間,你沿著這些道路從乙個房間走到另外乙個房間需要一些時間。遊戲規定了你的...
51nod 硬幣遊戲
有乙個簡單但是很有趣的遊戲。在這個遊戲中有乙個硬幣還有一張桌子,這張桌子上有很多平行線 如下圖所示 兩條相鄰平行線之間的距離是1,硬幣的半徑是r,然後我們來拋硬幣到桌子上,拋下之後硬幣有時候會和一些直線相交 相切的情況也算是相交 有時候不會。請你來計算一下拋一次硬幣之後,該硬幣和直線相交數目的期望。...