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
*/

  

 

posted @ 2020-08-29 23:44  风生  阅读(136)  评论(0编辑  收藏  举报