2024.10.16校测
T1
题目描述
给你一个无向带权连通图,每条边是黑色或白色。让你求一棵恰好有
输入格式
第一行
接下来
输出格式
一行表示所求生成树的边权和。
输入样例
3 3 1
1 2 100 1
1 3 20 0
2 3 25 0
输出样例
120
数据规模
对于
对于另外
对于所有数据,
完整代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5 + 9;
struct edge{
int u, v, c, val;
} E[N], tmp[N];
int n, m, need;
int fa[N], sum, cnt;
int find(int x){
return fa[x] == x ? x : fa[x] = find(fa[x]);
}
bool cmp(edge x, edge y){
if(x.val == y.val)
return x.c < y.c;
return x.val < y.val;
}
bool check(int x){
sum = 0, cnt = 0;
for(int i = 1; i <= n; i++)
fa[i] = i;
for(int i = 1; i <= m; i++){
tmp[i] = E[i];
if(!E[i].c)
tmp[i].val += x;
}
sort(tmp + 1, tmp + m + 1, cmp);
for(int i = 1; i <= m; i++){
int fu = find(tmp[i].u), fv = find(tmp[i].v);
if(fu != fv){
fa[fu] = fv;
sum += tmp[i].val;
cnt += !tmp[i].c;
}
}
return cnt >= need;
}
signed main(){
freopen("e2.in", "r",stdin);
freopen("e2.out", "w",stdout);
scanf("%lld%lld%lld", &n, &m, &need);
for(int i = 1; i <= m; i++)
scanf("%lld%lld%lld%lld", &E[i].u, &E[i].v, &E[i].val, &E[i].c);
int l = -1005, r = 1005, ans;
while(l < r){
int mid = (l + r) / 2;
if(check(mid)){
ans = sum - need * mid;
l = mid + 1;
} else
r = mid;
}
printf("%lld", ans);
return 0;
}
T2
题目描述
小
-
行交换操作:选择矩阵的任意两行,交换这两行(即交换对应格子的颜色)
-
列交换操作:选择矩阵的任意行列,交换这两列(即交换对应格子的颜色)
游戏的目标,即通过若干次操作,使得方阵的主对角线(左上角到右下角的连线)上的格子均为黑色。对于某些关卡,小
输入格式
第一行包含一个整数
接下来包含
输出格式
输出文件应包含 Yes
;否则输出一行 No
。
输入样例
2
2
0 0
0 1
3
0 0 1
0 1 0
1 0 0
输出样例
No
Yes
数据规模
对于
对于
完整代码
#include <bits/stdc++.h>
using namespace std;
const int N = 4e2 + 9;
int G[N][N];
int match[N], reserve_boy[N];
int a[N][N], n, T;
bool dfs(int x){
for(int i = n + 1; i <= 2 * n; i++)
if(!reserve_boy[i] && G[x][i]){
reserve_boy[i] = 1;
if(!match[i] || dfs(match[i])){
match[i] = x;
return true;
}
}
return false;
}
void init(){
memset(G, 0, sizeof(G));
memset(match, 0, sizeof(match));
memset(reserve_boy, 0, sizeof(reserve_boy));
}
int main(){
freopen("f.in", "r", stdin);
freopen("f.out", "w", stdout);
scanf("%d", &T);
while(T--){
init();
scanf("%d", &n);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++){
scanf("%d", &a[i][j]);
if(a[i][j] == 1)
G[i][j + n] = 1;
}
int sum = 0;
for(int i = 1; i <= n; i++){
memset(reserve_boy, 0, sizeof(reserve_boy));
if(dfs(i))
sum++;
}
if(sum == n)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
T3
题目描述
有两条蛇(
输入格式
第一行
接下来
输出格式
输出一行
输入样例
3 3
1 0 0
3 0 3
0 0 2
输出样例
2 5
数据规模
对于
对于
T4
题目描述
输入格式
第一行一个整数
对于每组数据:第一行两个整数
输出格式
对于每组数据,先输出一行一个整数
输入样例
4
4 3
2 4
1 3
3 2
2 2
1 2
2 1
3 1
2 3
4 4
1 2
2 4
3 4
1 3
输出样例
4
1 3 2 4
0
0
2
1 4
样例解释
在第二组数据中,由于政府不想看见重复的信息,因此他们无法入侵任何电脑。
在第三组数据中,
在第四组数据中,政府不能入侵电脑
数据规模
对于
对于
完整代码
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 9, M = 1e6 + 9;
struct Edge{
int v, nex;
} ori[M << 1], anti[M << 1], dom[M << 1];
int headori[N], headanti[N], headdom[N], oricnt, anticnt, domcnt;
void addori(int u, int v){
ori[++oricnt] = Edge{v, headori[u]};
headori[u] = oricnt;
}
void addanti(int u, int v){
anti[++anticnt] = Edge{v, headanti[u]};
headanti[u] = anticnt;
}
void adddom(int u, int v){
dom[++domcnt] = Edge{v, headdom[u]};
headdom[u] = domcnt;
}
int n, m;
int dfn_tar[N], low[N], ins[N], dfncnt_tar;
int scc[N], sc;
int sz[N];
stack <int> s;
void tarjan(int u) {
low[u] = dfn_tar[u] = ++dfncnt_tar, ins[u] = 1;
s.push(u);
for(int i = headori[u]; i; i = ori[i].nex) {
const int &v = ori[i].v;
if(!dfn_tar[v]){
tarjan(v);
low[u] = min(low[u], low[v]);
} else if(ins[v])
low[u] = min(low[u], dfn_tar[v]);
}
if(dfn_tar[u] == low[u]){
++sc;
while(s.top() != u){
scc[s.top()] = sc;
sz[sc]++;
ins[s.top()] = 0;
s.pop();
}
scc[s.top()] = sc;
sz[sc]++;
ins[s.top()] = 0;
s.pop();
}
}
int fat[N], dfn[N], mp[N], dfncnt;
int fa[N], semi[N], idom[N], mid[N], ans;
bool flag[N];
int find(int x){
if(fa[x] == x)
return x;
int fx = fa[x], y = find(fa[x]);
if(dfn[semi[mid[fx]]] < dfn[semi[mid[x]]])
mid[x] = mid[fx];
return fa[x] = y;
}
void dfs(int u, int father){
dfn[u] = ++dfncnt;
mp[dfncnt] = u;
fat[u] = father;
for(int i = headori[u]; i; i = ori[i].nex){
int v = ori[i].v;
if(!dfn[v])
dfs(v, u);
}
}
bool vis[N], loop[N];
void calc(int u, int typ){
vis[u] = true;
if(flag[u] && sz[scc[u]] == 1 && !loop[u] && typ == 1)
printf("%d ", u);
else if(flag[u] && sz[scc[u]] == 1 && !loop[u] && typ == 0)
ans++;
for(int i = headori[u]; i; i = ori[i].nex){
int v = ori[i].v;
if(vis[v])
continue;
calc(v, typ);
}
}
void Dominate(){
for(int i = n; i >= 2; i--){
int tmp = n, u = mp[i];
for(int j = headanti[u]; j; j = anti[j].nex){
int v = anti[j].v;
if(!dfn[v])
continue;
if(dfn[v] < dfn[u])
tmp = min(tmp, dfn[v]);
else {
int fv = find(v);
tmp = min(tmp, dfn[semi[mid[v]]]);
}
}
semi[u] = mp[tmp];
fa[u] = fat[u];
adddom(semi[u], u);
u = mp[i - 1];
for(int j = headdom[u]; j; j = dom[j].nex){
int v = dom[j].v;
int fv = find(v);
if(semi[mid[v]] == u)
idom[v] = u;
else
idom[v] = mid[v];
}
}
for(int i = 2; i <= n; i++){
int v = mp[i];
if(idom[v] != semi[v])
idom[v] = idom[idom[v]];
}
memset(headdom, 0, sizeof(headdom));
domcnt = 0;
for(int i = 1; i < n; i++)
adddom(idom[i], i);
for(int i = n; ;i = idom[i]){
if(i == 0)
break;
flag[i] = true;
}
calc(1, 0);
memset(vis, 0, sizeof(vis));
printf("%d\n", ans);
if(ans == 0){
printf("\n");
return;
}
calc(1, 1);
printf("\n");
}
void init(){
memset(vis, 0, sizeof(vis));
memset(fat, 0, sizeof(fat));
memset(dfn, 0, sizeof(dfn));
memset(mp, 0, sizeof(mp));
memset(idom, 0, sizeof(idom));
memset(flag, 0, sizeof(flag));
memset(dfn_tar, 0, sizeof(dfn_tar));
memset(low, 0, sizeof(low));
memset(ins, 0, sizeof(ins));
memset(scc, 0, sizeof(scc));
memset(sz, 0, sizeof(sz));
memset(headori, 0, sizeof(headori));
memset(headanti, 0, sizeof(headanti));
memset(headdom, 0, sizeof(headdom));
memset(loop, 0, sizeof(loop));
while(!s.empty())
s.pop();
ans = dfncnt = dfncnt_tar = sc = oricnt = anticnt = domcnt = 0;
}
int T;
int main(){
freopen("i.in", "r", stdin);
freopen("i.out", "w", stdout);
scanf("%d", &T);
while(T--){
init();
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++)
fa[i] = semi[i] = mid[i] = i;
for(int i = 1; i <= m; i++){
int u, v;
scanf("%d%d", &u, &v);
if(u == v){
loop[u] = true;
continue;
}
addori(u, v);
addanti(v, u);
}
tarjan(1);
if(dfn_tar[n] == 0 || scc[1] == scc[n])
printf("0\n");
else {
dfs(1, 0);
Dominate();
}
}
return 0;
}
本文来自博客园,作者:JPGOJCZX,转载请注明原文链接:https://www.cnblogs.com/JPGOJCZX/p/18470390
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App