图论练习4

内容:染色划分,带权并查集,扩展并查集

Arpa’s overnight party and Mehrdad’s silent entering

题目链接

题目大意

  • 2n个点围成一圈,分为n对,对内两点不同染色
  • 同时,相邻3个点之间必须有两个点不同染色
  • 问构造出一种染色方案

解题思路 

  •  将每对进行的连边看作一类边
  • 将为满足相邻3个点必须有两个点不同染色的边,看作二类边
  • 满足构造方案,即将2n个点形成一个二分图,无奇环
  • 对于只有一类边,形不成环,端点不同
  • 对于二类边与一类边组合才能形成环
  • 将二类边定义为2_i\leftrightarrow 2_i+1
  • 成环的情况只能,如下图
  • 由于一类边不可能相连,中间必然是二类边,一类边交换,所以环上的点数为二类边的总点数,一定为偶数,只能形成偶环,构造成立
  • 利用带权并查集实现

import java.io.*;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.BitSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.StringTokenizer;
import java.util.Vector;




public class Main{
	
	static int find(int x,int[] fa,int[] relation) {
		if(x==fa[x])return x;
		else {
			int f=fa[x];
			fa[x]=find(fa[x], fa, relation);
			relation[x]=(relation[x]+relation[f])%2;
			return fa[x];
		}
	}

	public static void main(String[] args) throws IOException{
		AReader input=new AReader();
	    PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
	    int n=input.nextInt();
	    int[] fa=new int[2*n+1];
	    int[] relation=new int[2*n+1];
	    for(int i=1;i<=2*n;++i)fa[i]=i;
	    int[] a=new int[n+1];
	    int[] b=new int[n+1];
	    for(int i=1;i<=n;++i) {
	    	int x=input.nextInt();
	    	int y=input.nextInt();
	    	a[i]=x;b[i]=y;
	    	int fx=find(x, fa, relation);
	    	int fy=find(y, fa, relation);
	    	if(fx==fy)continue;
	    	fa[fx]=fy;
	    	relation[fx]=(relation[y]+1-relation[x]+2)%2;
	    }
	    for(int i=1;i<=n;++i) {//一圈
	    	int x=2*i;
	    	int y=i==n?1:2*i+1;
	    	int fx=find(x, fa, relation);
	    	int fy=find(y, fa, relation);
	    	if(fx==fy)continue;
	    	fa[fx]=fy;
	    	relation[fx]=(relation[y]+1-relation[x]+2)%2;
	    }
	    for(int i=1;i<=n;++i) {
	    	find(a[i], fa, relation);
	    	find(b[i], fa, relation);
	    	int x=relation[a[i]]+1;
	    	int y=relation[b[i]]+1;
	    	out.println(x+" "+y);
	    }
 	    out.flush();
	    out.close();
	}
	static
	class AReader{
	    BufferedReader bf;
	    StringTokenizer st;
	    BufferedWriter bw;

	    public AReader(){
	        bf=new BufferedReader(new InputStreamReader(System.in));
	        st=new StringTokenizer("");
	        bw=new BufferedWriter(new OutputStreamWriter(System.out));
	    }
	    public String nextLine() throws IOException{
	        return bf.readLine();
	    }
	    public String next() throws IOException{
	        while(!st.hasMoreTokens()){
	            st=new StringTokenizer(bf.readLine());
	        }
	        return st.nextToken();
	    }
	    public char nextChar() throws IOException{
	        //确定下一个token只有一个字符的时候再用
	        return next().charAt(0);
	    }
	    public int nextInt() throws IOException{
	        return Integer.parseInt(next());
	    }
	    public long nextLong() throws IOException{
	        return Long.parseLong(next());
	    }
	    public double nextDouble() throws IOException{
	        return Double.parseDouble(next());
	    }
	    public float nextFloat() throws IOException{
	        return Float.parseFloat(next());
	    }
	    public byte nextByte() throws IOException{
	        return Byte.parseByte(next());
	    }
	    public short nextShort() throws IOException{
	        return Short.parseShort(next());
	    }
	    public BigInteger nextBigInteger() throws IOException{
	        return new BigInteger(next());
	    }
	    public void println() throws IOException {
	        bw.newLine();
	    }
	    public void println(int[] arr) throws IOException{
	        for (int value : arr) {
	            bw.write(value + " ");
	        }
	        println();
	    }
	    public void println(int l, int r, int[] arr) throws IOException{
	        for (int i = l; i <= r; i ++) {
	            bw.write(arr[i] + " ");
	        }
	        println();
	    }
	    public void println(int a) throws IOException{
	        bw.write(String.valueOf(a));
	        bw.newLine();
	    }
	    public void print(int a) throws IOException{
	        bw.write(String.valueOf(a));
	    }
	    public void println(String a) throws IOException{
	        bw.write(a);
	        bw.newLine();
	    }
	    public void print(String a) throws IOException{
	        bw.write(a);
	    }
	    public void println(long a) throws IOException{
	        bw.write(String.valueOf(a));
	        bw.newLine();
	    }
	    public void print(long a) throws IOException{
	        bw.write(String.valueOf(a));
	    }
	    public void println(double a) throws IOException{
	        bw.write(String.valueOf(a));
	        bw.newLine();
	    }
	    public void print(double a) throws IOException{
	        bw.write(String.valueOf(a));
	    }
	    public void print(char a) throws IOException{
	        bw.write(String.valueOf(a));
	    }
	    public void println(char a) throws IOException{
	        bw.write(String.valueOf(a));
	        bw.newLine();
	    }
	}
}

食物链 

题目链接 

题目大意

  • n个点,k对关系
  • 每个点可能为A/B/C类,它们之间满足ABBCCA
  • k对关系中,1,x,y表示x,y同类,2,x,y表示xy
  • 依次处理k对关系,若当前关系与之前的关系矛盾,则视为错误
  • x>n,y>n,(2,x,y)x=y(自己吃自己),均视为错误
  • 问有多少对错误

解题思路

  • n个点进行3种颜色的染色划分
  • 类似黑白染色
  • 利用带权并查集或扩展并查集实现
  • 详见图论笔记 

扩展并查集 

 
import java.io.*;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.BitSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.StringTokenizer;
import java.util.Vector;
 
 
 
 
public class Main{
	
	static int find(int x,int[] fa) {
		if(x==fa[x])return x;
		else return fa[x]=find(fa[x], fa);
	}
	
	
	
	public static void main(String[] args) throws IOException{
		AReader input=new AReader();
	    PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
	    int n=input.nextInt();
	    int k=input.nextInt();
	    int[] fa=new int[3*n+1];
	    for(int i=1;i<=3*n;++i)fa[i]=i;
	    int ans=0;
	    for(int i=1;i<=k;++i) {
	    	int op=input.nextInt();
	    	int x=input.nextInt();
	    	int y=input.nextInt();
	    	if(x>n||y>n) {
	    		ans++;
	    		continue;
	    	}
	    	if(op==1) {
	    		if(find(x, fa)==find(y+n, fa)||find(y, fa)==find(x+n, fa)) {
	    			//x吃y或y吃x
	    			//x吃y=>xA->yB,xB->yC,xC->yA
	    			//y吃x=>yA->xB,yB->xC->yC->xA
	    			ans++;
	    			continue;
	    		}
	    		fa[find(x, fa)]=find(y, fa);
	    		fa[find(x+n, fa)]=find(y+n, fa);
	    		fa[find(x+2*n, fa)]=find(y+2*n, fa);
	    	}else {
	    		if(x==y) {
	    			ans++;
	    			continue;
	    		}
	    		if(find(x, fa)==find(y, fa)||find(y, fa)==find(x+n, fa)) {
	    			//x和y是同类,y吃x
	    			ans++;
	    			continue;
	    		}
	    		fa[find(x, fa)]=find(y+n, fa);
	    		fa[find(x+n, fa)]=find(y+2*n, fa);
	    		fa[find(x+2*n, fa)]=find(y, fa);
	    	}
	    }
	    out.print(ans);
 	    out.flush();
	    out.close();
	}
	static
	class AReader{
	    BufferedReader bf;
	    StringTokenizer st;
	    BufferedWriter bw;
 
	    public AReader(){
	        bf=new BufferedReader(new InputStreamReader(System.in));
	        st=new StringTokenizer("");
	        bw=new BufferedWriter(new OutputStreamWriter(System.out));
	    }
	    public String nextLine() throws IOException{
	        return bf.readLine();
	    }
	    public String next() throws IOException{
	        while(!st.hasMoreTokens()){
	            st=new StringTokenizer(bf.readLine());
	        }
	        return st.nextToken();
	    }
	    public char nextChar() throws IOException{
	        //确定下一个token只有一个字符的时候再用
	        return next().charAt(0);
	    }
	    public int nextInt() throws IOException{
	        return Integer.parseInt(next());
	    }
	    public long nextLong() throws IOException{
	        return Long.parseLong(next());
	    }
	    public double nextDouble() throws IOException{
	        return Double.parseDouble(next());
	    }
	    public float nextFloat() throws IOException{
	        return Float.parseFloat(next());
	    }
	    public byte nextByte() throws IOException{
	        return Byte.parseByte(next());
	    }
	    public short nextShort() throws IOException{
	        return Short.parseShort(next());
	    }
	    public BigInteger nextBigInteger() throws IOException{
	        return new BigInteger(next());
	    }
	    public void println() throws IOException {
	        bw.newLine();
	    }
	    public void println(int[] arr) throws IOException{
	        for (int value : arr) {
	            bw.write(value + " ");
	        }
	        println();
	    }
	    public void println(int l, int r, int[] arr) throws IOException{
	        for (int i = l; i <= r; i ++) {
	            bw.write(arr[i] + " ");
	        }
	        println();
	    }
	    public void println(int a) throws IOException{
	        bw.write(String.valueOf(a));
	        bw.newLine();
	    }
	    public void print(int a) throws IOException{
	        bw.write(String.valueOf(a));
	    }
	    public void println(String a) throws IOException{
	        bw.write(a);
	        bw.newLine();
	    }
	    public void print(String a) throws IOException{
	        bw.write(a);
	    }
	    public void println(long a) throws IOException{
	        bw.write(String.valueOf(a));
	        bw.newLine();
	    }
	    public void print(long a) throws IOException{
	        bw.write(String.valueOf(a));
	    }
	    public void println(double a) throws IOException{
	        bw.write(String.valueOf(a));
	        bw.newLine();
	    }
	    public void print(double a) throws IOException{
	        bw.write(String.valueOf(a));
	    }
	    public void print(char a) throws IOException{
	        bw.write(String.valueOf(a));
	    }
	    public void println(char a) throws IOException{
	        bw.write(String.valueOf(a));
	        bw.newLine();
	    }
	}
}

 带权并查集

 
import java.io.*;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.BitSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.StringTokenizer;
import java.util.Vector;
 
 
 
 
public class Main{
	
	static int find(int x,int[] fa,int[] relation) {
		if(x==fa[x])return x;
		else {
			int f=fa[x];
			fa[x]=find(fa[x], fa, relation);
			relation[x]=(relation[x]+relation[f])%3;
			return fa[x];
		}
	}
	
	
	
	public static void main(String[] args) throws IOException{
		AReader input=new AReader();
	    PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
	    int n=input.nextInt();
	    int k=input.nextInt();
	    int ans=0;
	    int[] fa=new int[n+1];
	    int[] relation=new int[n+1];
	    for(int i=1;i<=n;++i) fa[i]=i;
	    for(int i=1;i<=k;++i) {
	    	int op=input.nextInt();
	    	int x=input.nextInt();
	    	int y=input.nextInt();
	    	if(x>n||y>n) {
	    		ans++;
	    		continue;
	    	}
	    	if(op==1) {
	    		int fx=find(x, fa, relation);
	    		int fy=find(y, fa, relation);
	    		if(fx==fy) {
	    			if(relation[x]!=relation[y]) {
	    				ans++;
	    				continue;
	    			}
	    		}else {
	    			fa[fx]=fy;
	    			relation[fx]=(relation[y]+0-relation[x]+3)%3;
	    		}
	    	}else {
	    		if(x==y) {
	    			ans++;
	    			continue;
	    		}
	    		int fx=find(x, fa, relation);
	    		int fy=find(y, fa, relation);
	    		if(fx==fy) {//0吃1,1吃2,2吃0
	    			if(relation[x]==0&&relation[y]==1||
	    					relation[x]==1&&relation[y]==2||
	    					relation[x]==2&&relation[y]==0)continue;
	    			ans++;
	    			continue;
	    		}else {
	    			fa[fx]=fy;
	    			relation[fx]=(relation[y]+2-relation[x]+3)%3;
	    		}
	    	}
	    }
	    out.println(ans);
 	    out.flush();
	    out.close();
	}
	static
	class AReader{
	    BufferedReader bf;
	    StringTokenizer st;
	    BufferedWriter bw;
 
	    public AReader(){
	        bf=new BufferedReader(new InputStreamReader(System.in));
	        st=new StringTokenizer("");
	        bw=new BufferedWriter(new OutputStreamWriter(System.out));
	    }
	    public String nextLine() throws IOException{
	        return bf.readLine();
	    }
	    public String next() throws IOException{
	        while(!st.hasMoreTokens()){
	            st=new StringTokenizer(bf.readLine());
	        }
	        return st.nextToken();
	    }
	    public char nextChar() throws IOException{
	        //确定下一个token只有一个字符的时候再用
	        return next().charAt(0);
	    }
	    public int nextInt() throws IOException{
	        return Integer.parseInt(next());
	    }
	    public long nextLong() throws IOException{
	        return Long.parseLong(next());
	    }
	    public double nextDouble() throws IOException{
	        return Double.parseDouble(next());
	    }
	    public float nextFloat() throws IOException{
	        return Float.parseFloat(next());
	    }
	    public byte nextByte() throws IOException{
	        return Byte.parseByte(next());
	    }
	    public short nextShort() throws IOException{
	        return Short.parseShort(next());
	    }
	    public BigInteger nextBigInteger() throws IOException{
	        return new BigInteger(next());
	    }
	    public void println() throws IOException {
	        bw.newLine();
	    }
	    public void println(int[] arr) throws IOException{
	        for (int value : arr) {
	            bw.write(value + " ");
	        }
	        println();
	    }
	    public void println(int l, int r, int[] arr) throws IOException{
	        for (int i = l; i <= r; i ++) {
	            bw.write(arr[i] + " ");
	        }
	        println();
	    }
	    public void println(int a) throws IOException{
	        bw.write(String.valueOf(a));
	        bw.newLine();
	    }
	    public void print(int a) throws IOException{
	        bw.write(String.valueOf(a));
	    }
	    public void println(String a) throws IOException{
	        bw.write(a);
	        bw.newLine();
	    }
	    public void print(String a) throws IOException{
	        bw.write(a);
	    }
	    public void println(long a) throws IOException{
	        bw.write(String.valueOf(a));
	        bw.newLine();
	    }
	    public void print(long a) throws IOException{
	        bw.write(String.valueOf(a));
	    }
	    public void println(double a) throws IOException{
	        bw.write(String.valueOf(a));
	        bw.newLine();
	    }
	    public void print(double a) throws IOException{
	        bw.write(String.valueOf(a));
	    }
	    public void print(char a) throws IOException{
	        bw.write(String.valueOf(a));
	    }
	    public void println(char a) throws IOException{
	        bw.write(String.valueOf(a));
	        bw.newLine();
	    }
	}
}

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 《图论导引》是一本经典的图论教材,作者是Richard Douglas。这本书主要介绍了图论的基本概念、算法和应用。全书共分为8章,包括简介、基本定义、树、度数和匹配、带权图和最短路径、网络流、图的着色和图的遍历。 这本书的优点在于,它提供了对图论的深入而易于理解的介绍。每个章节都包涵了很多练习题,其中大部分都有答案和详细解答,非常适合初学者自学和教师课程教学。另外,该书还附带了一些基本的编程代码和例子,帮助读者更好地理解算法和数据结构。 此外,《图论导引》还涉及了图论在现实生活和科学领域中的应用。例如,在网络流和图着色方面,书中探讨了公交路线和电路板设计等实际问题。这为读者提供了一种将理论知识应用于实际问题的实用方法。 总之,《图论导引》是一本非常好的引导读者深入了解图论的经典书籍。它适合初学者,也适合已有基础的读者,既可以做为课程教材,也可以做为自学资料。 ### 回答2: 《图论导引》(Introduction to Graph Theory)是美国著名数学家J. Douglas Faires所著的一本关于图论的入门教材,其PDF版即为“图论导引 Douglas pdf”。 该书囊括了图论的基础知识,包括图的定义、遍历、最短路、网络流、图的匹配、染色问题等内容,并给出了大量具体案例作为实例,方便读者理解概念和应用。 此外,《图论导引》还强调了图论在实际应用中的重要性,包括在计算机科学、物理、生物、工程等各个领域的应用,并指出图论在这些领域中的实际应用案例。 总体而言,《图论导引》是一本具有实用性和理论性的好书,它既能让初学者快速掌握图论的基础知识和应用,又能为进阶学习者提供丰富的经验和参考资料。因此,无论是学习图论的初学者还是专业研究者,都可以从这本书中获得很多启发和帮助。 ### 回答3: 《图论导引 Douglas pdf》是一本非常优秀的图论学习资料。这本书的作者是美国著名的计算机科学家阿尔弗雷德·道格拉斯(Alfred J. Ahlswede)。这本书的内容主要围绕着图论展开,从基础到进阶都有涉及。 《图论导引 Douglas pdf》详细介绍了图的基本概念、图的表示方法、图的遍历算法、连通性理论、最短路径算法、最小生成树算法、网络流算法、拓扑排序和强连通分量等内容。每一章的讲解都非常深入浅出,具有很高的实用性和可读性。同时,在书中还穿插了大量的例子来帮助读者更好地理解和掌握其中的知识点。 通过《图论导引 Douglas pdf》这本书的学习,读者可以深入了解图论的基本理论和应用,提高自己的算法设计和分析能力。这本书适合有一定的计算机科学基础的读者阅读,包括了计算机科学、数学等专业的学生以及从业人员。此外,这本书还可以作为一本优秀的参考书,供大家在实际工作中使用。总之,《图论导引 Douglas pdf》是一本非常值得阅读的图论学习资料,有兴趣的读者可以尝试一下。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值