2020/8/29
英语四级一篇
看了下析合树。
补了多校一题费用流+1题网络流题目
晚上打了场atcode



#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include"vector"
#include<queue>
#include"set"
#include"map"
using namespace std;
typedef long long ll;
inline int read(){
int s = 0, w = 1; char ch = getchar();
while(ch < '0' || ch > '9') { if(ch == '-') w = -1; ch = getchar(); }
while(ch >= '0' && ch <= '9') { s = (s << 3) + (s << 1) + (ch ^ 48); ch = getchar(); }
return s * w;
}
const int inf=1e9;
const int N=300,M=N*N+N+7,E=500005;
int ver[E], edge[E], Next[E], head[E];
int cost[E],d[M];
int incf[M], pre[M], v[M];
ll ans;
int n, k, tot, s, t, maxflow,m,q[E];
vector<int> G;
void add(int x, int y, int z, int c) {
// 正向边,初始容量z,单位费用c
ver[++tot] = y, edge[tot] = z, cost[tot] = c;
Next[tot] = head[x], head[x] = tot;
// 反向边,初始容量0,单位费用-c,与正向边“成对存储”
ver[++tot] = x, edge[tot] = 0, cost[tot] = -c;
Next[tot] = head[y], head[y] = tot;
}
bool spfa() {
queue<int> q;
for(int i = 0; i <= n + m + m + n; i ++) d[i] = inf;
memset(v, 0, sizeof(v));
q.push(s); d[s] = 0; v[s] = 1; // SPFA 求最长路
incf[s] = 1 << 30; // 增广路上各边的最小剩余容量
while (q.size()) {
int x = q.front(); v[x] = 0; q.pop();
for (int i = head[x]; i; i = Next[i]) {
if (!edge[i]) continue; // 剩余容量为0,不在残量网络中,不遍历
int y = ver[i];
if (d[y]>d[x] + cost[i]) {
d[y] = d[x] + cost[i];
incf[y] = min(incf[x], edge[i]);
pre[y] = i; // 记录前驱,便于找到最长路的实际方案
if (!v[y]) v[y] = 1, q.push(y);
}
}
}
if (d[t] == inf) return false; // 汇点不可达,已求出最大流
return true;
}
// 更新最长增广路及其反向边的剩余容量
void update() {
int x = t;
while (x != s) {
int i = pre[x];
edge[i] -= incf[t];
edge[i ^ 1] += incf[t]; // 利用“成对存储”的xor 1技巧
x = ver[i ^ 1];
}
G.push_back(d[t]);
maxflow += incf[t];
ans += d[t] * incf[t];
//printf("%d %d sd\n ",d[t],incf[t]);
}
int main() {
while(~scanf("%d%d",&n,&m)){
tot = 1; memset(head,0,sizeof(head));
G.clear(); memset(cost,0,sizeof(cost));
t = n; s = 1;
for(int i = 1; i <= m; i ++) {
int a = read(),b = read(),x = read();
add(a,b,1,x);
}
maxflow = ans = 0;
while(spfa()){
update();
//printf("%lld %lld\n",maxflow,ans);
}
// printf("%lld\n",ans);
int q = read();
while(q --){
int u = read(),v = read();
ll ansu = 0,ansv = v;
for(int i = 0; i < G.size(); i ++){
if(v > u){
v -= u;
ansu += G[i] * (ll)u;
} else {
ansu += G[i] * (ll)v;
v = 0;
}
}
if(v){
puts("NaN");
continue;
}
ll gcd=__gcd(ansu,ansv);
ansu/=gcd,ansv/=gcd;
printf("%lld/%lld\n",ansu,ansv);
}
}
}
#include"stdio.h"
#include"string.h"
#include"stack"
#include"map"
#include"math.h"
#include"iostream"
#include"vector"
#include"queue"
#include"algorithm"
using namespace std;
#define OK printf("\n");
#define Debug printf("this_ok\n");
#define INF 1e18
typedef long long ll;
#define scanll(a,b) scanf("%lld%lld",&a,&b);
#define scanl(a) scanf("%lld",&a);
#define printl(a,b) if(b == 0) printf("%lld ",a); else printf("%lld\n",a);
#define print_int(a,b) if(b == 0) printf("%d ",a); else printf("%d\n",a);
typedef pair<int,int> PII;
inline int read(){
int s = 0, w = 1; char ch = getchar();
while(ch < '0' || ch > '9') { if(ch == '-') w = -1; ch = getchar(); }
while(ch >= '0' && ch <= '9') { s = (s << 3) + (s << 1) + (ch ^ 48); ch = getchar(); }
return s * w;
}
const ll mod = 998244353;
const int N = 50010,M = 300010;
const double pi = acos(-1);
const int inf = 1 << 29;
const int dirx[4] = {-1,0,1,0};
const int diry[4] = {0,1,0,-1};
int n,m,t,s,tot;
ll maxflow,sum;
int head[N],ver[M],Next[M],edge[M],d[N];
int a[N],dp[N];
queue<int> q;
void add(int x,int y,int z){
ver[++ tot] = y; Next[tot] = head[x]; edge[tot] = z; head[x] = tot;
ver[++ tot] = x; edge[tot] = 0; Next[tot] = head[y]; head[y] = tot;
}
bool bfs(){
memset(d,0,sizeof(d));
while(q.size())q.pop();
q.push(s); d[s] = 1;
while(q.size()){
int x = q.front(); q.pop();
for(int i = head[x]; i; i = Next[i])
if(edge[i] && !d[ver[i]]){
q.push(ver[i]); d[ver[i]] = d[x] + 1;
if(ver[i] == t) return 1;
}
}
return 0;
}
int dinic(int x,ll flow){
if(x == t) return flow;
ll rest = flow,k;
for(int i = head[x]; i && rest; i = Next[i]){
if(edge[i] && d[ver[i]] == d[x] + 1){
k = dinic(ver[i],min(rest,(ll)edge[i]));
if(!k) d[ver[i]] = 0;
edge[i] -= k;
edge[i ^ 1] += k;
rest -= k;
}
}
return flow - rest;
}
int main(){
n = read();s = 2 * n + 1; t = s + 1;
int maxx = 0;
for(int i = 1; i <= n; i ++) a[i] = read();
if(n == 1){
printf("1\n1\n1\n"); return 0;
}
for(int i = 1; i <= n; i ++){
for(int j = 1; j < i; j ++){
if(a[i] >= a[j] && dp[j] > dp[i]){
dp[i] = dp[j];
}
}
dp[i] += 1;
maxx = max(maxx,dp[i]);
}
printf("%d\n",maxx);
tot = 1;
for(int i = 1; i <= n; i ++){
add(i,i + n,1);
if(dp[i] == 1) add(s,i,1);
if(dp[i] == maxx) add(i + n,t,1);
}
for(int i = 1; i <= n; i ++)
for(int j = i + 1; j <= n; j ++){
if(a[j] >= a[i] && dp[j] == dp[i] + 1){
add(i + n,j,1);
}
}
ll flow = 0;
while(bfs())
while(flow = dinic(s,inf)) maxflow += flow;
printf("%lld\n",maxflow);
tot = 1; memset(head,0,sizeof(head));
for(int i = 1; i <= n; i ++){
add(i,i + n,1);
if(dp[i] == 1) add(s,i,1);
if(dp[i] == maxx) add(i + n,t,1);
}
for(int i = 1; i <= n; i ++)
for(int j = i + 1; j <= n; j ++){
if(a[j] >= a[i] && dp[j] == dp[i] + 1){
add(i + n,j,1);
}
}
add(1,1 + n,inf);
add(s,1,inf);
if(dp[n] == maxx){
add(n,n + n,inf);
add(n + n,t,inf);
}
flow = 0;
maxflow = 0;
while(bfs())
while(flow = dinic(s,inf)) maxflow += flow;
printf("%lld\n",maxflow);
}
/*
3
1 2 3
2
2 6
*/
浙公网安备 33010602011771号