zoukankan      html  css  js  c++  java
  • 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
     ",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
    ",maxflow,ans);
            }
           // printf("%lld
    ",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
    ",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("
    ");
    #define Debug printf("this_ok
    ");
    #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
    ",a);
    #define print_int(a,b) if(b == 0) printf("%d ",a); else printf("%d
    ",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
    1
    1
    "); 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
    ",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
    ",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
    ",maxflow);
    }
    /*
    3
    1 2 3
    2
    2 6
    */
    

      

  • 相关阅读:
    IIS 浏览aspx页面出现无法显示XML页的解决方法分享
    好看的导航菜单
    C# FileUpload使用过程遇到的问题
    javascript之数组操作
    浅谈.NET下的多线程
    项目分页通用页
    npoi
    react webpack.config.js的配置及注释
    JS 解析Json 方法
    json解析
  • 原文地址:https://www.cnblogs.com/yrz001030/p/13584031.html
Copyright © 2011-2022 走看看