Description

Misha trains several ACM teams at the university. He is an experienced coach, and he does not underestimate the meaning of friendly and collaborative atmosphere during training sessions. It used to be that way, but one of the teams happened to win contests a little bit more often than others, and hence became slightly too big for their boots. That does not contribute to positive spirit which is essential for successful training. But Misha knows what to do!
Representatives of k teams participate in Misha’s training sessions, each team has three members. Alas, teams rarely attend en masse, but at least one member per team is always present, of course. During the next training session Misha is going to split everyone into npairs, so that each pair will include representatives of different teams. Players will play a mini-contest against each other in each pair.
A situation when no two mini-contests are won by representatives of one team is the one that suits Misha’s goals best. He may be somewhat cunning when selecting winner in each pair in order to achieve such situation. Find out whether Misha will succeed.

Input

The first line contains two numbers — n and k (1 ≤ n ≤ 10 5, 2 ≤ k ≤ 10 5). n lines follow. i-th of these contains two numbers x iy i (1 ≤ x iy i ≤ kx i ≠ y i) — the numbers of teams, whose representatives are in pair number i.
It is guaranteed that each team is represented in no less than one and no more than three pairs.

Output

If Misha is to succeed, output Yes in the first line. In each of the following n lines output one number — the number of team that is to win in the corresponding pair. If there are several answers, output any.
If Misha is to fail, output No in the only line.

Sample Input

input output
3 4
1 2
2 3
1 4
Yes
2
3
4
6 4
1 2
1 3
1 4
2 3
2 4
3 4
No

题意:给出n对点a,b  要求从没对点中选出一个,且最终选出的点n个数不能存在相同的。输入数据满足每种数最多出现3次,最少出现1次

思路:第i对点的编号2*i, 2*i+1,   因为每个数最多出现3次,那么完全可以枚举每个数,然后相同的数之间的编号连一条边,表示这两个编号不能同时选,这样跑完twosat就能得到一个满足情况的解或无解。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <cstdlib>
#include <map>
#include <set>
#include <cmath>
using namespace std;
const int N = 2e6 + ;
struct Edge {
int to, nex;
}e[N];
int head[N], tot;
void init() {
tot = ; memset(head, -, sizeof head);
}
void add(int u, int v) {
e[tot].to = v;
e[tot].nex = head[u];
head[u] = tot++;
}
int Low[N], DFN[N], Stack[N], Belong[N];
int Index, top;
int scc;
bool Instack[N];
int num[N]; void Tarjan(int u) {
int v;
Low[u] = DFN[u] = ++Index;
Stack[top++] = u;
Instack[u] = true; for(int i = head[u]; ~i; i = e[i].nex) {
v = e[i].to;
if(!DFN[v]) {
Tarjan(v);
if(Low[u] > Low[v]) Low[u] = Low[v];
}else if(Instack[v] && Low[u] > DFN[v]) Low[u] = DFN[v];
}
if(Low[u] == DFN[u]) {
scc++;
do
{
v = Stack[--top];
Instack[v] = false;
Belong[v] = scc;
num[scc]++;
}while(v != u);
}
}
bool solvable(int n) {
memset(DFN, , sizeof DFN);
memset(Instack, false, sizeof Instack);
memset(num, , sizeof num);
Index = scc = top = ;
for(int i = ; i < n; ++i) if(!DFN[i]) Tarjan(i); for(int i = ; i < n; i += ) {
if(Belong[i] == Belong[i ^ ]) return false;
}
return true;
} queue<int> q1, q2;
vector<vector<int> >dag;
int vis[N];
int indeg[N];
int cf[N];
void solve(int n) {
dag.assign(scc+, vector<int>());
memset(indeg, , sizeof indeg);
memset(vis, , sizeof vis);
for(int u = ; u < n; ++u) {
for(int i = head[u]; ~i; i = e[i].nex) {
int v = e[i].to;
if(Belong[u] != Belong[v]) {
dag[ Belong[v] ].push_back(Belong[u]);
indeg[ Belong[u] ]++;
}
}
}
for(int i = ; i < n; i += ) {
cf[ Belong[i] ] = Belong[i ^ ];
cf[ Belong[i ^ ] ] = Belong[i];
}
while(!q1.empty()) q1.pop();
while(!q2.empty()) q2.pop();
for(int i = ; i <= scc; ++i) if(indeg[i] == ) q1.push(i); while(!q1.empty()) {
int u = q1.front();
q1.pop();
if(vis[u] == ) {
vis[u] = ;
vis[ cf[u] ] = ;
}
int sz = dag[u].size();
for(int i = ; i < sz; ++i) {
indeg[ dag[u][i] ]--;
if(indeg[ dag[u][i] ] == ) q1.push(dag[u][i]);
}
}
}
int r[N];
vector<int> g[N];
int main() {
#ifdef LOCAL
freopen("in", "r", stdin);
#endif
int n, m;
while(~scanf("%d%d", &m, &n)) {
init();
int tot = ; int u, v;
for(int i = ; i < m; ++i) {
scanf("%d%d", &u, &v);
r[tot++] = u;
r[tot++] = v;
g[u].push_back( * i);
g[v].push_back( * i + );
} for(int i = ; i <= n; ++i) {
int sx = g[i].size();
for(int j1 = ; j1 < sx; ++j1) {
for(int j2 = j1 + ; j2 < sx; ++j2) {
int v1 = g[i][j1];
int v2 = g[i][j2];
add(v1, v2 ^ );
add(v2, v1 ^ );
}
}
}
if(solvable( * m)) {
solve( * m);
puts("Yes");
for(int i = ; i < m; ++i) {
if(vis[ Belong[ * i] ]) printf("%d\n", r[ * i + ]);
else printf("%d\n", r[ * i]);
}
}else puts("No");
}
return ;
}

最新文章

  1. 我厂 WiFi SDK 开源了, 直接开源 WiFi 万能钥匙核心功能,造福中小开发者
  2. php.exe php-cgi.exe php-win.exe的区别
  3. TSkinData 皮肤控件后最大最小提示英文Close的解决方法
  4. Excel应该这么玩——2、命名列:消除地址引用
  5. SVM实用操作: svmtrain and svmclassify
  6. PHP配置文件详解php.ini [转]
  7. 理解 Bias 与 Variance 之间的权衡
  8. rs.open 打开数据库权限问题 rs.open sql,conn,1,3 等后缀权限问题
  9. 如何通过PhpMyAdmin批量删除MYSQL数据库数据表
  10. DHTMLX 前端框架 建立你的一个应用程序教程(三)--添加一个菜单
  11. Linux系统编程(12)——shell基础
  12. 【转】 linux内核移植和驱动添加(三)
  13. beini破解无线
  14. Java中常用的正则表达式
  15. PHP中$GLOBALS和global的区别
  16. bboss oreach循环嵌套遍历map
  17. 开发函数计算的正确姿势 —— 使用 Fun Local 本地运行与调试
  18. 【nginx】nginx日常命令
  19. wireshark抓本地回环包
  20. 第18月第20天 tensorflow安装

热门文章

  1. java从基础知识(八)泛型
  2. win7下IIS的安装和配置 图文教程
  3. 取两个String数组的交集
  4. OpenCV中IplImage图像格式与BYTE图像数据的转换
  5. 详解SpringMVC中GET请求
  6. Spark基础知识汇总
  7. Unity3D配合AndroidStudio打包
  8. WCF调用
  9. ListView只更新某个item
  10. 分布式之ZookeeperMac安装