zoukankan      html  css  js  c++  java
  • SSF信息社团4月训练题目整理

    选一些写。

    Hint:可以点击右下角的目录符号快速跳转到指定位置

    上接:SSF信息社团3月训练题目整理

    4.6

    875C

    Link

    2-SAT,点 (c) 表示这个字符不变,点 (c+m) 表示变为大写。考虑这样两个串:

    [s_1=c_1c_2c_3c_4cdots\ s_2=c_1c_2c_3c_5cdots ]

    (c_4<c_5),则 (c_5) 如果变,(c_4) 必须变;(c_4) 如果不变,(c_5) 必须不变。连 (c_5+m o c_4+m,;c_4 o c_5)。若 (c_4>c_5),则 (c_4) 必须变,(c_5) 必须不变,连 (c_4 o c_4+m,;c_5+m o c_5)。跑一遍 SCC 缩点,选 SCC 编号较小的作为方案。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    using namespace std;
    const int N=2e5+10,M=N<<1;
    int head[N],ver[M],nxt[M],tot=0;
    void add(int x,int y)
    {
    	ver[++tot]=y;
    	nxt[tot]=head[x];
    	head[x]=tot;
    }
    int low[N],dfn[N],cnt=0,num=0,col[N],st[N],top=0;
    bool vis[N];
    void tarjan(int x)
    {
    	dfn[x]=low[x]=++num;
    	st[++top]=x;vis[x]=1;
    	for(int i=head[x];i;i=nxt[i])
    	{
    		int y=ver[i];
    		if(!dfn[y])
    		{
    			tarjan(y);
    			low[x]=min(low[x],low[y]);
    		} else if(vis[y]) low[x]=min(low[x],dfn[y]);
    	}
    	if(dfn[x]==low[x])
    	{
    		cnt++;int y=0;
    		do{
    			y=st[top--];
    			col[y]=cnt;
    			vis[y]=0;
    		}while(x!=y);
    	}
    }
    vector<int> v[N];
    bool check(vector<int> a,vector<int> b)
    {
    	int n=min(a.size(),b.size());
    	for(int i=0;i<n;i++)if(a[i]!=b[i])return false;
    	return true;
    }
    int main()
    {
    	int n,m;
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++)
    	{
    		int k;scanf("%d",&k);
    		for(int j=1;j<=k;j++)
    		{
    			int x;scanf("%d",&x);
    			v[i].push_back(x);
    		}
    	}
    	for(int i=1;i<n;i++)
    	{
    		if(check(v[i],v[i+1]))
    		{
    			if(v[i].size()<=v[i+1].size())continue;
    			else return puts("No"),0;
    		}
    		int c=min(v[i].size(),v[i+1].size());
    		for(int j=0;j<c;j++)
    		{
    			if(v[i][j]==v[i+1][j])continue;
    			if(v[i][j]<v[i+1][j])
    			{
    				add(v[i][j],v[i+1][j]);
    				add(v[i+1][j]+m,v[i][j]+m);
    			}
    			else
    			{
    				add(v[i][j],v[i][j]+m);
    				add(v[i+1][j]+m,v[i+1][j]);
    			}
    			break;
    		}
    	}
    	for(int i=1;i<=m*2;i++)if(!dfn[i])tarjan(i);
    	for(int i=1;i<=m;i++)if(col[i]==col[i+m])return puts("No"),0;
    	puts("Yes");int ans=0;
    	for(int i=1;i<=m;i++)ans+=(col[i+m]<col[i]);printf("%d
    ",ans);
    	for(int i=1;i<=m;i++)if(col[i+m]<col[i])printf("%d ",i);
    	return 0;
    }
    

    4.7

    852D

    Link

    二分答案 (t),网络流 check。Floyd 预处理出所有点对 ((u,v)) 的最短距离 (d(u,v)),若 (d(u,v)le operatorname{mid}),连 (u o v),流量为 (+infty);源点 (S) 连所有 (x_i),流量为 (1);所有点都连向汇点 (T),流量为 (1)。跑一遍最大流,若答案不小于 (k) 则合法。为了避免流混乱,需要把每个点 (u) 拆成两个:(u,;u+V)(u) 向外连边,(u+V) 接受连边。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    using namespace std;
    inline int read()
    {
    	int x=0,f=1;char c=getchar();
    	while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}
    	while(c>='0'&&c<='9') {x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    	return x*f;
    }
    const int N=1e6+10,inf=0x3f3f3f3f;
    int head[N],ver[N],edge[N],nxt[N],tot=1;
    void add(int x,int y,int z)
    {
    	ver[++tot]=y;
    	edge[tot]=z;
    	nxt[tot]=head[x];
    	head[x]=tot;
    }
    int dep[N];bool vis[N];
    int S,T; 
    bool bfs()
    {
    	memset(dep,0x3f,sizeof(dep));
    	memset(vis,0,sizeof(vis));
    	dep[S]=0;
    	queue<int> que;
    	que.push(S);
    	while(!que.empty())
    	{
    		int x=que.front();que.pop();
    		vis[x]=0;
    		for(int i=head[x];i;i=nxt[i])
    		{
    			int y=ver[i];
    			if(dep[x]+1<dep[y]&&edge[i])
    			{
    				dep[y]=dep[x]+1;
    				if(!vis[y])
    				{
    					vis[y]=1;
    					que.push(y);
    				}
    			}
    		}
    	}
    	return dep[T]!=inf;
    }
    int dfs(int x,int limit)
    {
    	if(x==T||!limit)return limit;
    	int flow=0,rlow=0;
    	for(int i=head[x];i;i=nxt[i])
    	{
    		int y=ver[i];
    		if(dep[y]==dep[x]+1&&edge[i])
    		{
    			if(rlow=dfs(y,min(limit,edge[i])))
    			{
    				edge[i]-=rlow;edge[i^1]+=rlow;
    				flow+=rlow;limit-=rlow;
    				if(!limit) break;
    			}
    		}
    	}
    	return flow;
    }
    int dinic()
    {
    	int ans=0;
    	while(bfs())ans+=dfs(S,inf);
    	return ans;
    }
    int x[N],dis[610][610],v,e,n,k;
    bool check(int mid)
    {
    	memset(head,0,sizeof(head));tot=1;
    	for(int i=1;i<=v;i++) add(i+v,T,1),add(T,i+v,0);
    	for(int i=1;i<=v;i++)
    	{
    		if(x[i]) add(S,i,x[i]),add(i,S,0);
    		for(int j=1;j<=v;j++)
    			if(dis[i][j]<=mid)
    				add(i,j+v,inf),add(j+v,i,0);
    	} 
    	int ans=dinic();
    	return ans>=k;
    }
    int main()
    {
    	v=read(),e=read(),n=read(),k=read();
    	S=0;T=v*2+2; 
    	for(int i=1;i<=n;i++) x[read()]++;
    	memset(dis,0x3f,sizeof(dis));
    	for(int i=1;i<=v;i++)dis[i][i]=0;
    	for(int i=1;i<=e;i++)
    	{
    		int x=read(),y=read(),z=read();
    		dis[x][y]=dis[y][x]=min(dis[x][y],z);
    	}
    	for(int k=1;k<=v;k++)
    		for(int i=1;i<=v;i++)
    			for(int j=1;j<=v;j++)
    				dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
    	int l=0,r=1731311,ans=-1;
    	while(l<=r)
    	{
    		int mid=(l+r)/2;
    		if(check(mid))r=mid-1,ans=mid;
    		else l=mid+1;
    	}
    	printf("%d",ans);
    	return 0;
    }
    
  • 相关阅读:
    Python 数据处理 正则匹配,清洗脏数据
    Pycharm自用激活码
    编程杂谈 集群与分布式
    win10 向右键添加管理员级CMD
    win10 笔记本键盘永久屏蔽Numlk键
    Golong 环境搭建
    python 各种锁机制归纳整理
    MySQL数据库操作
    Web框架本质
    Django框架
  • 原文地址:https://www.cnblogs.com/juruo-zzt/p/14623989.html
Copyright © 2011-2022 走看看