ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Loj#3320-「CCO 2020」旅行商问题

2022-08-11 19:00:57  阅读:122  来源: 互联网

标签:蓝色 Loj 路径 3320 int CCO 红色 include rightarrow


正题

题目链接:https://loj.ac/p/3320


题目大意

有一张\(n\)个点的无向完全图,每一条边是红色或者蓝色,对于每个点\(s\)求从这个点出发的一条尽量短的经过所有点的路径。

\(1\leq n\leq 2000\)


解题思路

显然地猜测一下最短的长度肯定是\(n\),说是找一条路径,实际上我们是能够找到一个颜色交替只有一次的环的,然后交替位置就在\(s\)的旁边。

我们构造一下,此时有两条不相交的路径\(s\rightarrow x,t\rightarrow y\),并且两条路径上颜色都相同,一条红色一条蓝色。

我们假设\(s\rightarrow x\)的路径是红色,此时对于一个未加入的点\(z\),如果\((x,z)\)是红色或者\((y,z)\)是蓝色那么直接加长路径即可。

否则也就是说\((x,z)\)是蓝色且\((y,z)\)是红色,我们考虑\((x,y)\)之间的路径颜色,假设是红色,那么如图
在这里插入图片描述
我们将\(y\)弹出路径\(t\rightarrow y\),然后加入\(s\rightarrow x\)后就可以再加入\(z\)了。

如果是蓝色同理弹另一边。

但是此时会出现两种情况:

  • 蓝色路径弹出后为空了,那么此时我们再找一个新的点当做新的\(t\)即可,反正我们的要求是\(s\)不变。
  • 红色路径弹出后为空了,那么此时我们将\(z\)作为新的\(t\),然后原本的\(s\rightarrow t\)路径变为\(s\rightarrow x\)路径。

时间复杂度:\(O(n^2)\)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int N=2100;
int n,G[N][N];
char s[N];
vector<int>l,r;
int main()
{
	scanf("%d",&n);
	if(n==2){
		printf("2\n1 2\n2\n2 1\n");
		return 0;
	}
	for(int i=2;i<=n;i++){
		scanf("%s",s+1);
		for(int j=1;j<i;j++)
			G[i][j]=G[j][i]=(s[j]=='R');
	}
	for(int s=1;s<=n;s++){
		int z=s%n+1,g=0;l.clear();r.clear();
		l.push_back(z);r.push_back(s);g=G[s][z%n+1];
		for(int x=z%n+1;x!=s;x=x%n+1){
			if(G[r[r.size()-1]][x]==g)r.push_back(x);
			else if(G[l[l.size()-1]][x]==!g)l.push_back(x);
			else{
				if(G[l[l.size()-1]][r[r.size()-1]]==g){
					r.push_back(l[l.size()-1]);
					r.push_back(x);l.pop_back();
					if(!l.size()){
						x=x%n+1;if(x==s)break;
						l.push_back(z=x);
					}
				}
				else{
					l.push_back(r[r.size()-1]);
					l.push_back(x);r.pop_back();
					if(!r.size()){
						l.pop_back();l.swap(r);
						l.push_back(x);z=x;g=!g;
					}
				}
			}
		}
		printf("%d\n",n);
		for(int i=0;i<r.size();i++)printf("%d ",r[i]);
		for(int i=l.size()-1;i>=0;i--)printf("%d ",l[i]);
		putchar('\n');
	}
	return 0;
}

标签:蓝色,Loj,路径,3320,int,CCO,红色,include,rightarrow
来源: https://www.cnblogs.com/QuantAsk/p/16577529.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有