• 2020/8/31


    英语四级

    学习替罪羊树 划分树

    四题

     

     

     

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    #define inf 1e9+7
    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 N = 5010, M = 200010;
    int ver[M], edge[M], cost[M], Next[M], head[N];
    int d[N], incf[N], pre[N], v[N],a[N];
    int n, k, tot, s, t, maxflow, ans;
    
    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; 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];
    	}
    	maxflow += incf[t];
    	ans += d[t] * incf[t];
    }
    
    int main() {
    	n = read(); int sum = 0;
    	s = n * 2 + 1; t = s + 1;
    	tot = 1; // 一会儿要从2开始“成对存储”,2和3是一对,4和5是一对
    	for (int i = 1; i <= n; i++){
    		a[i] = read();
    		sum += a[i];
        }
        sum /= n;
        for(int i = 1; i <= n; i ++){
            a[i] -= sum;
            if(a[i] < 0) {
                add(i + n,t,-a[i],0);
            } else {
                add(s,i,a[i],0);
            }
            if(i - 1 > 0) {
                add(i,i - 1,inf,1);
                add(i,i - 1 + n,inf,1);
            }
            if(i + 1 <= n) {
                add(i,i + 1,inf,1);
                add(i,i + 1 + n,inf,1);
            }
        }
        add(1,n,inf,1);
        add(1,n << 1,inf,1);
        add(n,1,inf,1);
        add(n,1 + n,inf,1);
    	while (spfa()) {update();} // 计算最大费用最大流
    	 cout  << ans << endl;
    
    }
    
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    #define inf 1e9+7
    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 N = 5010, M = 200010;
    int ver[M], edge[M], cost[M], Next[M], head[N];
    int d[N], incf[N], pre[N], v[N],m;
    int n, k, tot, s, t, maxflow, ans;
    int a[205][205],b[205][205],c[205][205][205];
    int need[205],sup[205],cnt;
    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; 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];
    	}
    	maxflow += incf[t];
    	ans += d[t] * incf[t];
    }
    
    int mincost(){
        ans = 0;
         while (spfa()) {update();} // 计算最大费用最大流
         return ans;
    }
    int main() {
        while(~scanf("%d%d%d",&n,&m,&k)){
            if(n == 0) break;
            memset(need,0,sizeof(need));
            memset(sup,0,sizeof(sup));
            s = n + m + 1; t = s + 1;
            tot = 1; // 一会儿要从2开始“成对存储”,2和3是一对,4和5是一对
            for(int i=1;i<=n;i++)
              for(int j=1;j<=k;j++){
                    a[i][j] = read();
                    need[j]+=a[i][j];
                }
            for(int i=1;i<=m;i++)
                for(int j=1;j<=k;j++){
                    b[i][j] = read();
                    sup[j]+=b[i][j];
                }
            for(int i=1;i<=k;i++)//最小花费
                for(int j=1;j<=n;j++)
                    for(int l=1;l<=m;l++)
                    c[i][j][l] = read();
            int flag=0;
            for(int i=1;i<=k;i++){
                if(sup[i]<need[i]){
                    flag=1;
                }
            }
            if(flag){
                printf("-1
    ");continue;
            }
            int ans = 0;
            for(int i=1;i<=k;i++)
            {
                memset(head,0,sizeof(head));cnt=0;
                for(int j=1;j<=m;j++)
                    add(s,j,b[j][i],0);
                for(int j=1;j<=n;j++)
                    add(j+m,t,a[j][i],0);
    
                for(int j=1;j<=n;j++)
                    for(int l=1;l<=m;l++){
                    add(l,j+m,inf,c[i][j][l]);
                    }
                ans+=mincost();
            }
            printf("%d
    ",ans);
        }
    
    
    #include <bits/stdc++.h>
    using namespace std;
    const int N=1e4+5;
    struct edge{
        double x,y1,y2;
        int k;
        bool operator <(const edge &t)const
        {
            return x<t.x;   
        }
    }op[N*2];
    
    struct node{
        int l,r,cnt;
        double len;
    }tr[N*8];
    
    vector<double>v;
    
    
    void pushup(int u)
    {
        if(tr[u].cnt)
        {
            tr[u].len=v[tr[u].r+1]-v[tr[u].l];
        }
        else if(tr[u].l!=tr[u].r)
        {
            tr[u].len=tr[u<<1].len+tr[u<<1|1].len;
        }
        else
        {
            tr[u].len=0;
        }
    }
    
    void modify(int u,int l,int r,int k)
    {
        if(l<=tr[u].l&&r>=tr[u].r)
        {
            tr[u].cnt+=k;
            pushup(u);
            return;
        }
        else
        {
            int mid=tr[u].l+tr[u].r>>1;
            if(l<=mid)    modify(u<<1,l,r,k);
            if(r>mid)     modify(u<<1|1,l,r,k);
            pushup(u);
        }
    }
    
    void build(int u,int l,int r)
    {
        if(l==r)
        {
            tr[u]={l,r,0,0};
            return;
        }
        else
        {
            int mid=l+r>>1;
            tr[u]={l,r,0,0};
            build(u<<1,l,mid);
            build(u<<1|1,mid+1,r);
        }
    }
    
    int find(double x)//寻找x的位子
    {
        return lower_bound(v.begin(),v.end(),x)-v.begin();
    }
    
    int main()
    {
        int n,T=1;
        while(cin>>n,n)
        {  
            v.clear();
            for(int i=0,j=0;i<n;i++)
            {
                double x1,y1,x2,y2;
                scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
                op[j++]={x1,y1,y2,1};
                op[j++]={x2,y1,y2,-1};
                v.push_back(y1);v.push_back(y2);
            }
            sort(v.begin(),v.end());
            v.erase(unique(v.begin(),v.end()),v.end());
            build(1,0,v.size()-2);
            sort(op,op+2*n);
            double ans=0.0;
            for(int i=0;i<2*n;i++)
            {
                if(i>0) ans+=tr[1].len*(op[i].x-op[i-1].x);
                modify(1,find(op[i].y1),find(op[i].y2)-1,op[i].k);
            }
            printf("Test case #%d
    ",T++);
            printf("Total explored area: %.2lf
    ",ans);
            puts("");
        }
        return 0;
    }
    }、
    
    
    #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 int inf = 1 << 29;
    const int dirx[4] = {-1,0,1,0};
    const int diry[4] = {0,1,0,-1};
    
    typedef struct Node{
        ll x,y,w;
        Node(){};
        Node(ll a,ll b,ll c){x = a; y = b; w = c;}
    }Node;
    
    Node node[N];
    int n,w,h;
    
    int cmpx(Node a,Node b){
        return a.x < b.x;
    }
    int cmpy(Node a,Node b){
        return a.y < b.y;
    }
    
    ll max_into(int i,int j){
       // printf("i = %d j = %d
    ",i,j);
        Node temp[30010];int top = 0;
        int x =i;
        for(i;i <= j; i ++)
            temp[++ top] = node[i];
        i = x;
    
        sort(temp + 1,temp + 1 + top,cmpy);
    
        ll value = 0,ans = 0;
        ll pre = -1;
        //for(int i = 1; i <= top; i ++)
        for(int i = 1; i <= top;i ++){
            if(pre == -1 || temp[i].y - temp[pre].y < h){
                ans += temp[i].w; value = max(ans,value);
                if(pre == -1) pre = i;
                continue;
            }
            while(pre <= i && temp[i].y - temp[pre].y >= h){
                ans -= temp[pre].w;
                pre ++;
            }
        }
        //printf("value = %lld
    ",value);
        return value;
    }
    int main(){
        while(~scanf("%d%d%d",&n,&w,&h)){
            for(int i = 1; i <= n; i ++)
                scanf("%lld%lld%lld",&node[i].x,&node[i].y,&node[i].w);
            sort(node + 1,node + 1 + n,cmpx);
            ll ans = 0;
            for(int i = 1; i <= n;i ++){
                int j = i;
                while(j < n && node[j + 1].x - node[i].x < w) j ++;
                ans = max(ans,max_into(i,j));
            }
            printf("%lld
    ",ans);
        }
    }
    

      

  • 相关阅读:
    高并发的一些处理意见
    TP5单元测试
    你真的会玩SQL吗?和平大使 内连接、外连接
    微信公众号第三方平台开发概况
    MVC的基类
    Android TextView中显示图片
    Android之assets资源
    通用分页存储过程
    到处都是坑的微信支付V3之 微信支付回调页面
    微信公众平台无高级接口账号获取用户基本信息
  • 原文地址:https://www.cnblogs.com/yrz001030/p/13594011.html
Copyright © 2020-2023  润新知