• BZOJ 2718/1533 Violet 4 毕业旅行


    2718: [Violet 4]毕业旅行

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 676  Solved: 391
    [Submit][Status][Discuss]

    Description

    Input

    Output

    最多可选多少景点

    Sample Input

    7 6
    1 2
    2 3
    5 4
    4 3
    3 6
    6 7

    Sample Output

    2

    HINT

    Source

     
    用floyed传递背包求出那两个点之间可以到达
    剩下的不就是在一个二分图中求出最大独立集么么?最大独立集=总点数-二分图最大匹配数(也就是最小点覆盖)
    dinic跑二分图最大匹配数的复杂度是O(n*sqrt(n))
    #include <bits/stdc++.h>
    #define ll long long
    #define inf 1e9+10
    using namespace std;
    inline int read(){
    	int x=0;int f=1;char ch=getchar();
    	while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    	while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    	return x*f;
    }
    const int MAXN=5e4+10;
    struct node{
    	int y,next,flow,back;
    }e[MAXN];
    int linkk[MAXN],len,n,head,tail,q[MAXN],level[1000],s,t,v[210][210],m;
    inline void insert(int x,int y,int f){
    	e[++len].y=y;e[len].next=linkk[x];linkk[x]=len;e[len].back=len+1;e[len].flow=f;
    	e[++len].y=x;e[len].next=linkk[y];linkk[y]=len;e[len].back=len-1;e[len].flow=0;
    }
    inline bool getlevel(){
    	head=tail=0;
    	memset(level,-1,sizeof(level));
    	q[++tail]=s;level[s]=0;
    	while(head<tail){
    		int tn=q[++head];
    		for(int i=linkk[tn];i;i=e[i].next){
    			if(e[i].flow&&level[e[i].y]==-1){
    				level[e[i].y]=level[tn]+1;
    				q[++tail]=e[i].y;
    			}
    		}
    	}
    	return level[t]>=0;
    }
    inline int getmaxflow(int x,int flow){
    	if(x==t) return flow;
    	int f=0,d;
    	for(int i=linkk[x];i;i=e[i].next){
    		if(level[e[i].y]==level[x]+1&&e[i].flow){
    			if(d=getmaxflow(e[i].y,min(flow-f,e[i].flow))){
    				e[i].flow-=d;f+=d;e[e[i].back].flow+=d;
    				if(f==flow) return f;
    			}
    		}
    	}
    	if(f==0) level[x]=-1;
    	return f;
    }
    inline int dinic(){
    	int ans=0,d;
    	while(getlevel()){
    		while(d=getmaxflow(s,inf)) ans+=d;
    	}
    	return ans;
    }
    void build(){
    	s=0,t=2*n+1;
    	for(int k=1;k<=n;k++){
    		for(int i=1;i<=n;i++){
    			for(int j=1;j<=n;j++){
    				v[i][j]|=(v[i][k]&v[k][j]);
    			}
    		}
    	}
    	for(int i=1;i<=n;i++){
    		insert(s,i,1);insert(i+n,t,1);
    	}
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=n;j++){
    			if(v[i][j]) insert(i,j+n,inf);
    		}
    	}
    }
    int main(){
    	n=read();m=read();
    	for(int i=1;i<=m;i++){
    		int x=read();int y=read();
    		v[x][y]=1;
    	}
    	build();
    	printf("%d
    ",n-dinic());
    	return 0;
    }
    

      

  • 相关阅读:
    CSS总结(六)——元素的垂直居中(已知高度/未知高度)
    CSS总结(五)——定位 position
    CSS总结(四)—— CSS选择器优先级
    CSS总结(三)—— 盒子模型(标准/IE下)
    CSS总结(二)—— 浮动 与 清除浮动
    CSS总结(一)—— display三种元素(区别、重点、扩展)
    JavaScript学习笔记(九)—— JS 理解闭包
    严格模式use strict
    let、const和var的区别
    字符串方法
  • 原文地址:https://www.cnblogs.com/something-for-nothing/p/8975905.html
Copyright © 2020-2023  润新知