【CF27D】Ring Road 2(二分图、紫题)

Ring Road 2 - 洛谷

第一道独立AC的紫题。(十分激动)

# Ring Road 2

## 题面翻译

有n个城市,1->2->3->...->n->1,形成一个环,现在要添加m条给定的路,路可以建设在环内或环外,求如何建设可以使得新的路两两不相交(端点除外)。

## 题目描述

It is well known that Berland has $ n $ cities, which form the Silver ring — cities $ i $ and $ i+1 $ ( $ 1<=i&lt;n $ ) are connected by a road, as well as the cities $ n $ and $ 1 $ . The goverment have decided to build $ m $ new roads. The list of the roads to build was prepared. Each road will connect two cities. Each road should be a curve which lies inside or outside the ring. New roads will have no common points with the ring (except the endpoints of the road).

Now the designers of the constructing plan wonder if it is possible to build the roads in such a way that no two roads intersect (note that the roads may intersect at their endpoints). If it is possible to do, which roads should be inside the ring, and which should be outside?

## 输入格式

The first line contains two integers $ n $ and $ m $ ( $ 4<=n<=100,1<=m<=100 $ ). Each of the following $ m $ lines contains two integers $ a_{i} $ and $ b_{i} $ ( $ 1<=a_{i},b_{i}<=n,a_{i}≠b_{i} $ ). No two cities will be connected by more than one road in the list. The list will not contain the roads which exist in the Silver ring.

## 输出格式

If it is impossible to build the roads in such a way that no two roads intersect, output Impossible. Otherwise print $ m $ characters. $ i $ -th character should be i, if the road should be inside the ring, and o if the road should be outside the ring. If there are several solutions, output any of them.

## 样例 #1

### 样例输入 #1

```
4 2
1 3
2 4
```

### 样例输出 #1

```
io
```

## 样例 #2

### 样例输入 #2

```
6 3
1 3
3 5
5 1
```

### 样例输出 #2

```
ooo
```

核心思路

考虑矛盾的两个条件相互连边,判断二分图。

二分图的作用——对两个矛盾的东西进行取舍

矛盾存在,仅当 存在 区间交叉(而非分离或者包含)

AC代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
vector<int> g[100010];
int d[100010],c1,c2,ans,t = 1;
bool dfs(int u,int color){
	//cout<<u<<endl;
	d[u] = color;
	if(d[u] == 1)c1++;
	else c2++;
	for(int v:g[u]){
	
		if(!d[v]){
			if(dfs(v,-color) == 0){
				return 0;
			} 
		}
		else if(d[u] == d[v]){
			return 0;
		}
	}
	return 1;
}
int a[114151],x,n,m,cnt;
int u[114000],v[101412];
bool check(int l1,int r1,int l2,int r2){//l1 l2 r1
	if(l1 < l2&&l2 < r1&&r1 < r2)return 1;
	return 0;
}
signed main(){
	cin>>n>>m;
	for(int k = 1;k <= m;k++){
		int x,y;
		cin>>x>>y;
		if(x > y)swap(x,y);
		//cout<<x<<" "<<y<<endl;
		for(int j = k-1;j>=1;j--){
			
			if(check(x,y,u[j],v[j])||check(u[j],v[j],x,y)){
			//	cout<<"PPP"<<x<<" "<<y<<" "<<u[j]<<" "<<v[j]<<endl;
				g[k].push_back(j);
				g[j].push_back(k);
			}
		}
		
		u[k] = x,v[k] = y;
	}
	for(int i = 1;i <= m;i++){
		if(!d[i]&&!dfs(i,1)){
			cout<<"Impossible";
			return 0;
		}
	}
	for(int i = 1;i <= m;i++){
		if(d[i] == 1){
			cout<<"o";
		}
		else{
			cout<<"i";
		}
	}
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值