作者 陈越 单位 浙江大学 代码长度限制 16KB 时间限制 200 ms 内存限制 64 MB
输入n,k,m,n表示一共有n个人要进行排座位,m条关系条数(A B S i S_i Si)表示A和B之间的关系为 S i S_i Si,然后进行k次查询,问两人是否能连着坐在一起
关系为1表示是朋友,-1表示是死对头
对每个查询输出一行结果:
通过二维数组存储两人之间的关系,由于两人之间的关系是唯一的,所以可以看做是 双向边
纯枚举做法不管怎么改都过不去,而最好的情况也会有全联通的测试点无法通过,因此判断是后能满足条件
因此,上网查询了一下并查集做法
未得分点:最大N,全连通环,全查询
acwing并查集 模板题
find(x) 是找会祖宗节点, p[x] 数组存放的是父节点
#include
#include
#include
using namespace std;
const int MAXN = 111;
int p[MAXN];
int find(int x) {
if (p[x] == x) return p[x];
return p[x] = find(p[x]);
}
//把能够成为好友的全部合并到一个根上
void merge(int x, int y){
int t1 = find(x);
int t2 = find(y);
if (t1 != t2){
p[t1] = t2;
}
}
int gx[MAXN][MAXN];
int main(){
int n, m, k; scanf("%d%d%d", &n, &m, &k);
for(int i = 1; i <= n; i++) p[i] = i;
for(int fi = 1; fi <= m; ++fi) {
int a, b, c; scanf("%d%d%d", &a, &b, &c);
gx[a][b] = c; gx[b][a] = c;
if (c == 1) merge(a, b);
}
for(int qu = 1; qu <= k; ++qu){
int qa, qb; scanf("%d%d", &qa, &qb);
if (gx[qa][qb] == 1) puts("No problem");
else if (gx[qa][qb] == -1){
if (find(qa) == find(qb))puts("OK but..."); else puts("No way");}
else {
if (find(qa) == find(qb)) puts("No problem"); else puts("OK");}
}
}
我们希望首先攻下敌方的部分城市,使其剩余的城市变成孤立无援,然后再分头各个击破。为此参谋部提供了若干打击方案。本题就请你编写程序,判断每个方案的可行性。
建图,数据大小和多边的存在,因此更适合vector的动态二维数组去建立邻接表,像最短路那样建
处理,通过vis去进行标记,vis[x] = 1说明这个城市已经被攻下了
访问,通过两层for循环去进行遍历,外层城市总数,内层该城市所连接的v[i].size()座城市
当 v i s [ i ] = = 0 且 v i s [ v [ i ] [ j ] ] = = 0 vis[i] == 0 且 vis[v[i][j]] == 0 vis[i]==0且vis[v[i][j]]==0的时候就说明存在城市不是孤立无援的,因此直接标记为策略失败
#include
#include
#include
#include
using namespace std;
const int maxn = 1e5 + 1111;
const int N = 111;
int vis[maxn];
vector<int> v[maxn]; // 链接表
void init1(){
memset(vis, 0, sizeof vis);
}
int main(){
int n, m; cin >> n >> m;
for(int si = 1; si <= m; si++){
int a, b; cin >> a >> b;
//双向边
v[a].push_back(b);
v[b].push_back(a);
}
int k; cin >> k;
// k种方案,使其剩余的城市变成孤立无援
for(int sk = 1; sk <= k; ++sk){
bool flag = true; //用于判断是否能够攻击成功
init1();
int np; cin >> np;
for(int sp = 1; sp <= np; ++sp){
int x; cin >> x; vis[x] = 1; //x城市已经被进攻
}
for(int i = 0; i < n; i++){
for(int j = 0; j < v[i].size(); j++){
if (vis[i] == 0 && vis[v[i][j]] == 0){
//确保都没进攻过
flag = false;
}
}
}
(flag) ? puts("YES") : puts("NO");
}
}
从m个垃圾站里面选取1个站点,让该站点离居民区的最近的人最远,并且没有超出服务范围ds之内。
如果有很多个最远的垃圾站,输出距离所有居民区距离平均值最小的那个。如果平均值还是一样,就输出按照顺序排列垃圾站编号最小的那个
最短路+字符处理
\\没写完,别看别看别看
#include
using namespace std;
const int MAXN = 1E5 + 50;
int d[MAXN];
bool vis[MAXN];//优化,判断是否松弛过
vector<pair<int, int >> E[MAXN];
inline void init(){
for(int i = 0; i < MAXN; i++) d[i] = INF;
for(int i = 0; i < MAXN; i++) E[i].clear();
for(int i = 0; i < MAXN; i++) vis[i] = false;
}
//迪杰斯特拉
void dij(){
int n, m, s; scanf("%d%d%d", &n, &m, &s);
priority_queue <PII, vector< PII >, greater<PII >> p;
init();
REP(i, m){
int x, y, z; RD(x, y, z);
E[x].push_back(MP(y, z));
}
//Dij
p.push(PII( 0, s)), d[s] = 0;
while(!p.empty()){
pair<int, int> now = p.top(); p.pop();
if (now.first != d[now.second])continue;
for(PII u: E[now.second]){
if (d[u.first] > d[now.second] + u.second){
d[u.first] = d[now.second] + u.second;
p.push(make_pair(d[u.first], u.first));
}
}
}
FOR_1(i, 0, n - 1){
if (d[i] == INF) cout << "INF" << '\n';
else cout << d[i] << '\n';
}
}
int main(){
int n, m, k, ds; cin >> n >> m >> k >> ds;
return 0;
}