zoukankan      html  css  js  c++  java
  • AcWing 343. 排序

    一种不用Floyd的方法。

    时间复杂度

    每组 (O(mn))

    Description

    对于每个输入。
    例如 A<B,我们由BA连一条有向边,表示AB小。
    通过这样连边,从B出发可以遍历到的所有点都是小于B的,其他字母同理。
    于是在每次连边之前,例如 A<B,先判断A在之前的不等式连成的图上能否遍历到B

    * 若能,则前后矛盾,输出: "Inconsistency found after t relations.",解决了第二问。
    * 若不能,向图中加入此条边,继续。
    

    接着判断是否两两关系确定。
    此条件等价于

    1. DAG上有且只有一个点的入度为0.
    2. topsort一遍后,每个点的深度f[i],互不相同。(f[u]=max(f[v])+1,v 是可直接访问到 u 的点);
    3. 不存在f[i]=0,(令入度为0的点的深度为1);
    

    证明:

    1. 两两关系确定那肯定只有一个最大的点 <------> 入度为0.
    2. 没有相等的点 <----> 每个点的深度f[i],互不相同.
    3. 不存在没有关系中的点 <------> 不存在f[i]=0.
    

    如果确定,f[i] 即为 char(i+'A'-1) 输出时的位置。
    输出。
    不确定就继续。
    直到关系加完了,还没确定,那就不确定。

    C++ 代码

    #include<queue>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    typedef long long LL;
    typedef unsigned long long ULL;
    using namespace std;
    const int N=36,M=10000+5;
    vector<int> v[N];
    bool vis[N];
    int dep[N];
    void dfs(int x)
    {
    	int i,y;
    	vis[x]=true;
    	for(i=0;i<(int)v[x].size();i++) {
    		y=v[x][i];
    		if(!vis[y]) 
    			dfs(y);
    	}
    	return;
    }
    queue<int> q;
    int f[N],d[N];
    int n,m;
    bool topsort()
    {
    	while(q.size()) q.pop();
    	memset(f,0,sizeof f);
    	memset(vis,0,sizeof vis);
    	memcpy(d,dep,sizeof d);
    	int i,x,y;
    	for(i=1;i<=n;i++) 
    		if(d[i]==0) 
    			q.push(i),f[i]=1;
    	if(q.size()>=2) return false;
    	vis[1]=true;
    	while(q.size()) {
    		x=q.front(); q.pop();
    		for(i=0;i<(int)v[x].size();i++) {
    			y=v[x][i];
    			f[y]=max(f[y],f[x]+1);
    			d[y]--;
    			if(d[y]==0) {
    				q.push(y);
    				if(vis[f[y]]) return false;
    				vis[f[y]]=true;
    			}
    		}
    	}
    	for(i=1;i<=n;i++) 
    		if(f[i]==0) 
    			return false;
    	return true;
    }
    
    int main()
    {
    //	freopen("1.in","r",stdin);
    	int i,j,ii;
    	int x,y;
    	char ch;
    	while(scanf("%d%d",&n,&m)==2) {
    		if(n==0&&m==0) break;
    		for(i=1;i<=n;i++)
    			v[i].clear();
    		memset(dep,0,sizeof dep);
    		for(i=1;i<=m;i++) {
    			cin>>ch; x=ch-'A'+1;
    			cin>>ch;
    			cin>>ch; y=ch-'A'+1;
    			memset(vis,0,sizeof vis);
    			dfs(x);
    			if(vis[y]) {
    				printf("Inconsistency found after %d relations.
    ",i);
    				break;
    			}
    			v[y].push_back(x);
    			dep[x]++;
    			if(topsort()) {
    				printf("Sorted sequence determined after %d relations: ",i);
    				for(ii=n;ii>=1;ii--) {
    					for(j=1;j<=n;j++) {
    						if(f[j]==ii) {
    							printf("%c",j+'A'-1);
    							break;
    						}
    					}
    				}
    				printf(".
    ");
    				break;
    			}
    		}
    		if(i<m+1) 
    			for(i++;i<=m;i++) 
    				cin>>ch>>ch>>ch;
    		else printf("Sorted sequence cannot be determined.
    ");
    	}
    	return 0;
    }
    

    注意事项

    1. 多组数据,记得清空.
    2. 要 memcpy 一个 dep[] 来 topsort ,否则 dep[] 会被修改.
    3. 不能一确定就 continue ,还得把本组剩下的无用数据都读入。
    
  • 相关阅读:
    查看端口有没有被占用
    微信公众号2()
    How to insert a segment of noise to music file
    puppet practice
    Docker Commands
    LempelZiv algorithm realization
    The algorithm of entropy realization
    Java network programmingguessing game
    Deploy Openstack with RDO and Change VNC console to Spice
    puppet overview
  • 原文地址:https://www.cnblogs.com/cjl-world/p/14054061.html
Copyright © 2011-2022 走看看