CodeForces 141E: ...(最小生成树)
[条件转换] 两两之间有且只有一条简单路径<==>树
题意:一个图中有两种边,求一棵生成树,使得这棵树中的两种边数量相等。
思路:
可以证明,当边的权是0或1时,可以生成最小生成树到最大生成树之间的任意值的生成树。
那么,方法就是生成最小生成树,然后,尽量替换0边,使得其成为值为(n-1)/2的生成树。
代码:
写的很乱,没有条理。还是应当先写出流程伪码后再敲代码的。
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
#define PB push_back
#define N 1020
struct Edge{
int to;
int cost;
int id;
Edge(int a = , int b = , int c = ): to(a), cost(b), id(c){};
};
vector<Edge> e[N]; int n, m; int dis[N];
int vis[N];
struct Node{
int cost;
int id;
int edgeid;
Node(int a=, int b=, int c=):cost(a),id(b),edgeid(c){}
bool operator < (const Node &b) const {
return cost > b.cost;
}
};
priority_queue<Node> que; int prim() {
while(!que.empty()) que.pop();
memset(dis,0x3f,sizeof(dis));
memset(vis,,sizeof(vis));
dis[] = ;
que.push(Node(,,));
int sum = ;
while (!que.empty()) {
int nowcost = que.top().cost;
int nowid = que.top().id;
int nowedgeid = que.top().edgeid;
que.pop();
if (vis[nowid]) continue; //printf("(%d) ", nowedgeid);
sum += nowcost;
vis[nowid] = true; for (int i = ; i < e[nowid].size(); i++) {
int to = e[nowid][i].to;
int cost = e[nowid][i].cost;
if (vis[to]) continue;
if (dis[to] > cost) {
dis[to] = cost;
que.push(Node(cost, to, e[nowid][i].id));
}
}
}
return sum;
} void solveprim(int changetime) {
//printf("changetime = %d\n", changetime);
vector<int> edgeids;
while(!que.empty()) que.pop();
memset(dis,0x3f,sizeof(dis));
memset(vis,,sizeof(vis));
dis[] = ;
que.push(Node(,,));
int sum = ;
while (!que.empty()) {
int nowcost = que.top().cost;
int nowid = que.top().id;
int nowedgeid = que.top().edgeid;
que.pop();
if (vis[nowid]) continue; if (nowedgeid != ) {
if (changetime > && nowcost == ) {
bool change = false;
for (int i = ; i < e[nowid].size(); i++) {
int to = e[nowid][i].to;
int cost = e[nowid][i].cost;
if (vis[to] && cost == ) {
changetime--;
//printf("change! %d\n", e[nowid][i].id);
edgeids.push_back(e[nowid][i].id);
change = true;
break;
}
}
if (!change) {
edgeids.push_back(nowedgeid);
}
} else {
edgeids.push_back(nowedgeid);
}
}
sum += nowcost;
vis[nowid] = true; for (int i = ; i < e[nowid].size(); i++) {
int to = e[nowid][i].to;
int cost = e[nowid][i].cost;
if (vis[to]) continue;
if (dis[to] > cost) {
dis[to] = cost;
que.push(Node(cost, to, e[nowid][i].id));
}
}
} if (changetime != ) puts("-1");
else {
printf("%d\n", edgeids.size());
for (int i = ; i < edgeids.size(); i++) {
printf("%d ", edgeids[i]);
}puts("");
}
return ;
} int main() {
while (scanf("%d%d", &n, &m) != EOF) {
for (int i = ; i <= n; i++) {
e[i].clear();
}
for (int i = ; i <= m; i++) {
int u, v;
char type[];
scanf("%d%d%s", &u, &v, type);
if (u == v) continue;
e[u].PB(Edge(v, type[] == 'S', i));
e[v].PB(Edge(u, type[] == 'S', i));
}
if (n% == ) {
printf("-1\n");
continue;
}
int minsum = prim();
int should = (n-)/;
//printf("minsum = %d\n", minsum);
if (minsum <= should) {
solveprim(should-minsum);
} else {
printf("-1\n");
continue;
}
}
return ;
}
CodeForces 141E: ...(最小生成树)的更多相关文章
- codeForces 472D 最小生成树
题目大意:给出一个图中点的两两距离,问是否是一棵树,若是,求出平均边权最大的点 prim最小生成树,若原图是树,则最小生成树的距离就是原距离.否则不是. 搞出来树了,第二问随便dfs就好了. #inc ...
- Xor-MST CodeForces - 888G (最小生成树,分治)
大意: n结点无向完全图, 给定每个点的点权, 边权为两端点异或值, 求最小生成树
- Mobile Phone Network CodeForces - 1023F (最小生成树)
大意: 无向图, 其中k条边是你的, 边权待定, m条边是你对手的, 边权已知. 求如何设置边权能使最小生成树中, 你的边全被选到, 且你的边的边权和最大. 若有多棵最小生成树优先取你的边. 先将$k ...
- The Shortest Statement CodeForces - 1051F 最小生成树+并查集+LCA
题目描述 You are given a weighed undirected connected graph, consisting of n vertices and mm edges. You ...
- Abandoning Roads CodeForces - 1149D (最小生成树)
大意: 给定无向图, 边权只有两种, 对于每个点$x$, 输出所有最小生成树中, 点$1$到$x$的最短距离. 先将边权为$a$的边合并, 考虑添加边权为$b$的边. 每条路径只能经过每个连通块一次, ...
- @codeforces - 141E@ Clearing Up
目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个 N 个点 M 条边的图,每条为黑色或者白色. 现在让你 ...
- 正睿OI国庆DAY2:图论专题
正睿OI国庆DAY2:图论专题 dfs/例题 判断无向图之间是否存在至少三条点不相交的简单路径 一个想法是最大流(后来说可以做,但是是多项式时间做法 旁边GavinZheng神仙在谈最小生成树 陈主力 ...
- Educational Codeforces Round 3 E. Minimum spanning tree for each edge (最小生成树+树链剖分)
题目链接:http://codeforces.com/contest/609/problem/E 给你n个点,m条边. 问枚举每条边,问你加这条边的前提下组成生成树的权值最小的树的权值和是多少. 先求 ...
- 【最小生成树】Codeforces 707B Bakery
题目链接: http://codeforces.com/problemset/problem/707/B 题目大意: 给你N个点M条无向边,其中有K个面粉站,现在一个人要在不是面粉站的点上开店,问到面 ...
随机推荐
- 【状态压缩dp】1195: [HNOI2006]最短母串
一个清晰的思路就是状压dp:不过也有AC自动机+BFS的做法 Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T ...
- 【AC自动机】bzoj4327: JSOI2012 玄武密码
题目思路没话讲:主要是做题时候的细节和经验 Description 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便消失在了进香河中 ...
- LeetCode935
问题:935. 骑士拨号器 国际象棋中的骑士可以按下图所示进行移动: . 这一次,我们将 “骑士” 放在电话拨号盘的任意数字键(如上图所示)上,接下来,骑士将会跳 N-1 步. ...
- python入门:数字型和字符串换行要同类型 注意连接符
#!/usr/bin/env python # -*- coding: utf-8 -*- #数字型和字符串换行要同类型 注意连接符 a = 1 b = 2 print(str(a) + " ...
- html5音频audio对象处理以及ios微信端自动播放和息屏后唤醒的判断---可供参考(功能都完整实现了,只是细节还没处理的很好)
// html模版中的 此处结合了weui样式整合的微信手机端片段代码(不可直接粘贴复制进行使用)里面含有一些php的写法,可直接略过..###重点参考js代码### <div> < ...
- request response cookie session
request 1. url传递参数 1)参数没有命名, 如: users/views def weather(request, city, year): print(city) print(year ...
- PAT Basic 1075
1075 链表元素分类 给定一个单链表,请编写程序将链表元素进行分类排列,使得所有负值元素都排在非负值元素的前面,而 [0, K] 区间内的元素都排在大于 K 的元素前面.但每一类内部元素的顺序是不能 ...
- Splay的用法
splay区间增减查询 #include<cstdio> #include<algorithm> using namespace std; ; const int INF = ...
- 异常 ndroid.view.InflateException: Binary XML file line #8: Error inflating class com.ouyang.test.MyView
发现自定义view时出现ndroid.view.InflateException: Binary XML file line #8: Error inflating class com.ouyang. ...
- Pycharm Django开发(一)设置开发环境
一 由于我是一个对开发环境有强迫症的人,在装完PYTHON 2.6 3.3 3.4中,在创建Django工程的时候,会出现N个版本的python,那么在这里可以设置你喜欢和要使用的版本.