zoukankan      html  css  js  c++  java
  • 8.26

    又双叒叕把U盘忘在寝室了,所以把今下午的代码拷在这里

    /*
    reference:
    	
    translation:
    	有q次操作。每次会选定一个矩形区域。具体的每次给一组(x_1,y_1),(x_2,y_2)表示矩阵的左
    	下角和右上角。在这个矩阵所覆盖的每一个格子里,累加一个积木块。每个积木块可以可以抽
    	象为一个的正方体。现在,Venn想知道他们堆出来的物体的表面积。 
    solution:
    【首先这并不是在线的询问,而是只询问一次,所以我们考虑对每个操作O(1)差分一下。】 
    	1.n*m*q的暴力算法显然不可取,采用二维差分O(1)预处理,O(n^2)查询a[i][j]的高度。
    	2.如果这个位置有高度,ans+=2;(上表面和下表面),其他四个面看周围四个的心情 
    trigger:
    	
    note:
    	*二维差分
    	*表面积问题 
    record:
    	这道题开long long 会爆内存………………………………………… 
    date:
    	2019.08.26
    */
    
    #define N 5001
    int n,m,q;
    int cnt[N][N];
    int main(){
        rd(n);rd(m);rd(q);
        while(q--){
            int x1,y1,x2,y2;rd(x1);rd(y1);rd(x2);rd(y2);
            cnt[x1][y1]++;
            cnt[x1][y2+1]--;
            cnt[x2+1][y1]--;
            cnt[x2+1][y2+1]++;
        }
        rep(i,1,n+1)
        	rep(j,1,m+1)
    			cnt[i][j]+=cnt[i-1][j]+cnt[i][j-1]-cnt[i-1][j-1];
        long long ans=0;
        rep(i,1,n+1){
        	rep(j,1,m+1){
                if(cnt[i][j])ans+=2;
                ans+=abs(cnt[i][j]-cnt[i-1][j])+abs(cnt[i][j]-cnt[i][j-1]);
            }
        }
        printf("%lld
    ",ans);
        return 0;
    }
    /*
    4 4 3
    1 1 4 4
    1 1 2 2
    3 3 4 4
    */
    
    //64
    
    /*
    4 4 1
    1 1 2 2
    */
    //16
    

    dij

    /*
    reference:
    	
    translation:
    	
    solution:
    
    trigger:
    	
    note:
    	*
    record:
    
    date:
    	2019.08.26
    */
    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    #define dwn(i,a,b) for(int i=a;i>=b;--i) 
    template <typename T> inline void rd(T &x){x=0;char c=getchar();int f=0;while(!isdigit(c)){f|=c=='-';c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}x=f?-x:x;} 
    inline void write(int n){if(n==0)return;write(n/10);putchar(n%10+'0');}
    #define mem(a,b) memset(a,b,sizeof(a))
    #define ee(i,u) for(int i=head[u];i;i=e[i].next)
    
    #define N 100010
    
    int head[N],cnt,dis[N];
    bool vis[N];
    
    struct Edge{
    	int v,next,w;
    }e[N<<1];
    
    void add(int u,int v,int w){e[++cnt].v=v;e[cnt].w=w;e[cnt].next=head[u];head[u]=cnt;}
    
    priority_queue<pair<int,int> > q;
    int n,m,s;
    
    inline void dij(){
    	mem(dis,0x3f);
    	mem(vis,0);
    	q.push(make_pair(0,1));
    	dis[1]=0;
    	while(!q.empty()){
    		int u=q.top().second;
    		q.pop();
    		if(vis[u])continue;
    		vis[u]=1;
    		ee(i,u){
    			int v=e[i].v,w=e[i].w;
    			if(dis[v]>dis[u]+w){
    				dis[v]=dis[u]+w;
    				q.push(make_pair(-dis[v],v));
    			}
    		}
    	}
    }
    
    int main(){
        rd(n),rd(m);
        rep(i,1,m){
    		int x,y,z;rd(x),rd(y),rd(z);
            add(x,y,z);
        }
        dij();
    	printf("%d ",dis[n]==0x3f3f3f3f?-1:dis[n]);
        return 0;
    }
    

    *问你是否存在负环的时候(没说S点),要把每一个点都作为起点spfa一遍

    	rep(i,1,n){
        	if(spfa(i)){
        		printf("Yes
    ");
        		exit(0);
    		}
    	}
        printf("No
    ");
    

    最小费用最大流

    /*给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用。
    第一行包含四个正整数N、M、S、T,分别表示点的个数、有向边的个数、源点序号、汇点序号。
    接下来M行每行包含四个正整数ui、vi、wi、fi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi),单位流量的费用为fi。
    一行,包含两个整数,依次为最大流量和在最大流量情况下的最小费用。*/
    /*
    reference:
    	
    translation:
    	
    solution:
    
    trigger:
    	
    note:
    	*
    record:
    
    date:
    	2019.08.26
    */
    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    #define dwn(i,a,b) for(int i=a;i>=b;--i) 
    template <typename T> inline void rd(T &x){x=0;char c=getchar();int f=0;while(!isdigit(c)){f|=c=='-';c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}x=f?-x:x;} 
    inline void write(int n){if(n==0)return;write(n/10);putchar(n%10+'0');}
    #define mem(a,b) memset(a,b,sizeof(a))
    #define ee(i,u) for(int i=head[u];i;i=e[i].next)
    
    #define N 100010
    bool vis[N];
    int n,m,s,t,x,y,z,f,cnt=1,maxflow,mincost;
    int head[N],dis[N],pre[N],last[N],flow[N];
    
    struct edge{int v,next,flow,cost;}e[N];
    queue<int>q;
    void add(int u,int v,int flow,int cost){
    	e[++cnt].v=v;e[cnt].flow=flow;e[cnt].cost=cost;e[cnt].next=head[u];head[u]=cnt;
    	e[++cnt].v=u,e[cnt].flow=0;e[cnt].cost=-cost;e[cnt].next=head[v];head[v]=cnt;
    }
    
    bool spfa(int s,int t){
    	mem(dis,0x7f);
    	mem(vis,0);
    	mem(flow,0x7f);
    	q.push(s);
    	vis[s]=1;
    	dis[s]=0;
    	pre[t]=-1;
    	while(!q.empty()){
    		int u=q.front();
    		q.pop();
    		vis[u]=0;
    		ee(i,u){
    			int v=e[i].v,cost=e[i].cost;
    			if(e[i].flow && dis[v]>dis[u]+cost){
    				dis[v]=dis[u]+cost;
    				pre[v]=u;
    				last[v]=i;
    				flow[v]=min(flow[u],e[i].flow);
    				if(!vis[v]){
    					vis[v]=1;
    					q.push(v);
    				}
    			}
    		}
    	}
    	return pre[t]!=-1;
    }
    
    int main(){
    	#ifdef WIN32
    	freopen("zxfyzdl.txt","r",stdin);
        #endif
        rd(n),rd(m),rd(s),rd(t);
        rep(i,1,m){
        	int u,v,cost,flow;rd(u),rd(v),rd(flow),rd(cost);
        	add(u,v,flow,cost);
    	}
    	while(spfa(s,t)){
    		int u=t;
    		maxflow+=flow[t];
    		mincost+=flow[t]*dis[t];
    		while(u!=s){
    			e[last[u]].flow-=flow[t];
    			e[last[u]^1].flow+=flow[t];
    			u=pre[u];
    		}
    	}
        printf("%d %d",maxflow,mincost);
        return 0;
    }
    /*
    4 5 4 3
    4 2 30 2
    4 3 20 3
    2 3 20 1
    2 1 30 9
    1 3 40 5
    */
    //50 280
    

    树的重心(WA)

    /*
    reference:
    	
    translation:
    	
    solution:
    
    trigger:
    	
    note:
    	*
    record:
    
    date:
    	2019.08.26
    */
    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    #define dwn(i,a,b) for(int i=a;i>=b;--i) 
    template <typename T> inline void rd(T &x){x=0;char c=getchar();int f=0;while(!isdigit(c)){f|=c=='-';c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}x=f?-x:x;} 
    inline void write(int n){if(n==0)return;write(n/10);putchar(n%10+'0');}
    #define mem(a,b) memset(a,b,sizeof(a))
    #define ee(i,u) for(int i=head[u];i;i=e[i].next)
    
    #define N 10010
    #define M 
    
    struct edge{
    	int v,next;
    }e[N<<1];
    
    int head[N],cnt,n,ans=INT_MAX,size[N];
    
    inline void add(int u,int v){e[++cnt].v=v;e[cnt].next=head[u];head[u]=cnt;}
    
    int dfs(int u,int fa){
        size[u]=1;
    	int max_sub_tree=0;
        ee(i,u){
            int v=e[i].v;
            if(v==fa)continue;
            int t=dfs(v,u);
            max_sub_tree=max(max_sub_tree,t);
            size[u]+=t;
        }
        max_sub_tree=max(max_sub_tree,n-size[u]);
        ans=min(ans,max_sub_tree);
        return size[u]+1;
    }
    
    #undef int
    int main(){
    #define int long long
    	#ifdef WIN32
    	freopen("zhongxin.txt","r",stdin);
    	#endif
    	rd(n);
    	rep(i,1,n-1){
    		int u,v;rd(u),rd(v);
    		add(u,v),add(v,u);
    	}
    	dfs(1,0);
    	printf("%lld
    ",ans);
    	//rep(i,1,n)printf("%lld ",size[i]); 
    	return 0;
    }
    /*
    9
    1 2
    1 7
    1 4
    2 8
    2 5
    4 3
    3 9
    4 6
    */
    //4
    

    toposort

    • 判断是否有TOPO排序:记录的序列已经到达n个了
    /*
    reference:
    	
    translation:
    	
    solution:
    
    trigger:
    	
    note:
    	*
    record:
    	妈个鬼仙人啊,数组没开够,我还以为是哪里写错了 T^T 
    date:
    	2019.08.26
    */
    #define N 100010
    
    struct edge{
    	int v,next;
    }e[N];
    
    int head[N],cnt,n,m,tot,deg[N],topon[N];
    
    void add(int u,int v){e[++cnt].v=v;e[cnt].next=head[u];head[u]=cnt;}
    
    queue<int>q;
    bool topo(){
    	rep(i,1,n)
    		if(!deg[i])
    			q.push(i);
    	while(!q.empty()){
    		int u=q.front();q.pop();
    		topon[++tot]=u;
    		ee(i,u){
    			int v=e[i].v;
    			if(--deg[v]==0)
    				q.push(v);
    		}
    	}
    	return tot==n;//////////////////////
    }
    
    int main(){
    	#ifdef WIN32
    	freopen("","r",stdin);
    	#endif
    	rd(n),rd(m);
    	rep(i,1,m){
    		int u,v;rd(u),rd(v);
    		add(u,v);deg[v]++;
    	}
    	if(topo()){
    		rep(i,1,tot)
    			printf("%d ",topon[i]);
    	}
    	else printf("-1
    ");
    	return 0;
    }
    /*
    
    
    3 3
    1 2
    2 3
    1 3
    
    */
    //1 2 3 
    

    floyd

    note:
    	*如果有负权边,虽然a,b不连通,但之间的距离也会因为负权边的更新小于INF,
    	因为INF/2也是一个很大的数,所以就用>INF/2来代表不能连通
    	*一定要把dis[i][i]赋值为0!
        *可能会有重边
    rep(i,1,n)dis[i][i]=0;/////////////////////////////
    
    dis[x][y]=min(dis[x][y],z);///////////////////////
    
    if(dis[x][y]>0x3f3f3f3f/2)printf("impossible
    ");
    else printf("%d
    ",dis[x][y]);
    

    二分图最大匹配

    /*
    reference:
    	
    translation:
    	
    solution:
    
    trigger:
    	
    note:
    	*
    record:
    
    date:
    	2019.08.26
    */
    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    #define dwn(i,a,b) for(int i=a;i>=b;--i) 
    template <typename T> inline void rd(T &x){x=0;char c=getchar();int f=0;while(!isdigit(c)){f|=c=='-';c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}x=f?-x:x;} 
    #define mem(a,b) memset(a,b,sizeof(a))
    #define ee(i,u) for(int i=head[u];i;i=m[i].next)
    
    #define N 1010
    int n1,n2,m,g[N][N],match[N],vis[N];
    
    inline bool dfs(int u){
    	rep(v,1,n2){
    		if(g[u][v]==1 && vis[v]==0){
    			vis[v]=1;
    			if(match[v]==0 || dfs(match[v])){
    				match[v]=u;
    				return 1;
    			}
    		}
    	}
    	return 0;
    } 
    
    #undef int
    int main(){
    #define int long long
    	#ifdef WIN32
    	freopen("","r",stdin);
    	#endif
    	rd(n1),rd(n2),rd(m);
    	while(m--){
    		int u,v;rd(u),rd(v);
    		g[u][v]=1;
    	}
    	int ans=0;//为新郎找姑娘 
    	mem(match,0);//初始化一下,目前新娘还没有被占领 
    	rep(i,1,n1){//枚举新郎 
    		mem(vis,0);//每次都重做一遍二分图匹配 
    		if(dfs(i))ans++;//恭喜i号新郎找到林妹妹 
    	}
    	printf("%d",ans);
    	return 0;
    }
    /*
    2 2 4
    1 1
    1 2
    2 1
    2 2
    */
    //2
    

    二分图染色

    • col初始化为-1,通过~操作可得到-2和1
    • 通过bfs来染色,注意要维护编号和一维值的关系时,可以make_pair
    #define N 200010
    
    int head[N],tot,col[N],s1,cnt,n,m;
    bool vis[N];
    
    struct edge{
    	int v,w,next;
    }e[N<<1];
    
    inline void add(int u,int v){e[++tot].v=v;e[tot].next=head[u];head[u]=tot;}
    
    queue<pair<int,int> >q;
    inline bool bfs(){
    	col[1]=1;
    	q.push(make_pair(1,1));
    	while(!q.empty()){
    		int u=q.front().first;
    		int color=q.front().second;
    		q.pop();
    		ee(i,u){
    			int v=e[i].v;
    			if(col[v]==-1){
    				col[v]=~color;
    				q.push(make_pair(v,col[v]));
    			}
    			else if(col[v]==col[u])return 0; 
    		}
    	}
    	return 1;
    } 
    
    int main(){
    	freopen("erfen.txt","r",stdin);
    	rd(n),rd(m);
    	rep(i,1,m){
    		int u,v;rd(u),rd(v);
    		add(u,v),add(v,u);
    	}
    	mem(col,-1);
    	if(bfs())printf("Yes
    ");
    	else printf("No
    ");
    	return 0;
    } 
    /*
    4 4
    1 3
    1 4
    2 3
    2 4
    */
    //Yes
    
  • 相关阅读:
    LA 2038 Strategic game(最小点覆盖,树形dp,二分匹配)
    UVA 10564 Paths through the Hourglass(背包)
    Codeforces Round #323 (Div. 2) D 582B Once Again...(快速幂)
    UVALive 3530 Martian Mining(贪心,dp)
    UVALive 4727 Jump(约瑟夫环,递推)
    UVALive 4731 Cellular Network(贪心,dp)
    UVA Mega Man's Mission(状压dp)
    Aizu 2456 Usoperanto (贪心)
    UVA 11404 Plalidromic Subsquence (回文子序列,LCS)
    Aizu 2304 Reverse Roads(无向流)
  • 原文地址:https://www.cnblogs.com/sjsjsj-minus-Si/p/11634784.html
Copyright © 2011-2022 走看看