A题
Description
题目描述
给N条边,请找三条边,使其组成一个三角形,并使得这个三角形的周长最大。
输入
存在多个样例。 第一行是一个整数N(3 ≤N
输出
输出最大周长三角形的周长,如果不能组成三角形,输出0 。
样例输入
5
5 3 4 10 2
0
样例输出
12
Sample Input
Sample Output
#include <bits/stdc++.h>
using namespace std ;
const int maxn = 10010 ;
int a[maxn];
int main () {
int n;
while (~scanf ("%d" ,&n)&&n){
for (int i = 0 ;i < n;i++)scanf ("%d" ,&a[i]);
sort(a,a+n);
__int64 res = 0 ;
for (int i = n-1 ;i>=2 ;i--){
if (a[i]<(a[i-1 ]+a[i-2 ])){
res = max(res,(__int64)a[i] + a[i-1 ] + a[i-2 ]);
}
}
printf ("%I64d\n" ,res);
}
return 0 ;
}
B题
题目描述
Robb想知道阶乘n! 第m位数码是什么?
输入
第一行是一个整数T , ( 1 ≤T ≤10000 )
每行一个样例,为2 个整数n, m, 0 ≤n≤1000 , 1 ≤m≤log10n! + 1
输出
每行输出一个样例的结果
样例输入
3
5 1
5 2
5 3
样例输出
0
2
1
#include <bits/stdc++.h>
using namespace std ;
const int maxn = 1010 ;
int a[maxn];
int Map[maxn][maxn];
int Find (int a, int i, int m)
{
int tp = Map[a][i];
for (int j = 0 ; j < m - 1 ; j++)
{
tp /= 10 ;
}
printf ("%d\n" , tp % 10 );
}
int main () {
memset (Map,0 ,sizeof (Map));
Map[0 ][0 ] = 1 ;
int n = 1 ;
for (int i = 1 ;i < 1001 ;i++){
int tmp = 0 ;
for (int j = 0 ;j < n;j++){
Map[i][j] = Map[i-1 ][j] * i;
Map[i][j] += tmp;
tmp = Map[i][j] / 10000 ;
Map[i][j] %= 10000 ;
if (tmp !=0 && j == n-1 ){
n++;
}
}
a[i] = n;
}
int t;
scanf ("%d" ,&t);
while (t--){
int n,m;
scanf ("%d%d" ,&n,&m);
Find(n,(m-1 )/5 ,m%5 ==0 ?5 :m%5 );
}
return 0 ;
}
C题
Rank
[ Submit Code ] [ Top 20 Runs ] [ Runs Status ]
Acceteped : 137 Submit : 546
Time Limit : 1000 MS Memory Limit : 65536 KB
Description
题目描述
给你N 个数,M 次询问,每次询问给定的数在这N 个数升序中能排第几(相同数的排名相同)?
输入
第一行输入两个数N (N≤100000 ),M (M≤100000 )。 第二行是N 个数,每个数处于[1,109] 之间。 第三行是M 个数,表示M 次询问,每次询问的数为[1,109] 之间。
输出
每行输出一次询问的排名,排名从1 开始算。
样例输入
5 5
1 1 3 4 5
1 2 3 4 5
样例输出
1
3
3
4
5
#include <bits/stdc++.h>
using namespace std ;
const int maxn = 100010 ;
int n,m;
int a[maxn];
int bsearch (int x) {
int mid;
int low = 0 ;
int high = n-1 ;
while (low <= high){
mid =(low + high)/2 ;
if (x <= a[mid])high = mid-1 ;
else low = mid + 1 ;
}
return low;
}
int main () {
while (~scanf ("%d%d" ,&n,&m)){
for (int i = 0 ;i < n;i++)scanf ("%d" ,&a[i]);
sort(a,a+n);
for (int i = 0 ;i < m;i++){
int t;
scanf ("%d" ,&t);
printf ("%d\n" ,bsearch(t)+1 );
}
}
return 0 ;
}
D题
Euler
[ Submit Code ] [ Top 20 Runs ] [ Runs Status ]
Acceteped : 94 Submit : 164
Time Limit : 2000 MS Memory Limit : 65536 KB
Description
题目描述
给你一个联通无向图,请问是否可以一笔画出来?
输入
样例的第一行是一个整数T,表示样例的个数。 每个样例的第一行是两个整数N(2≤N≤1,000)和 M(1≤M≤100,000), 分别表示顶点数和边数。顶点编号从1到N,以后的M行为边,每行两个整数, 表示边两个端点的序号。
输出
每行输出一个样例的结果,如果可以一笔画出,输出Yes,否则输出No。
样例输入
2
2 1
1 2
4 3
1 2
1 3
1 4
#include <bits/stdc++.h>
using namespace std ;
const int maxn = 1002 ;
int a[maxn];
int main () {
int T;
scanf ("%d" ,&T);
while (T--){
int n,m;
memset (a,0 ,sizeof (a));
scanf ("%d%d" ,&n,&m);
for (int i = 0 ;i < m;i++){
int t1,t2;
scanf ("%d%d" ,&t1,&t2);
a[t1]++;
a[t2]++;
}
int p = 0 ;
for (int i = 1 ;i <= n;i++){
if (a[i]&1 )p++;
}
if (p==2 ||p==0 )puts ("Yes" );
else puts ("No" );
}
}
E题
一个栈,支持三种操作:
PUSH x ,将x 压入栈中
POP ,将栈顶弹掉
MIN,输出当前栈中最小值,如果栈为空,输出NULL
给你一个操作列表,请模拟其操作过程。
输入
第一行是一个整数K,表示样例的个数。 每个样例的第一行是一个整数M,表示操作命令的数目1 ≤M≤100 ,000 。 以后的M行,每行一条命令,栈中所有值处于[0 ,1000000000 ]之间。
输出
每个MIN命令输出一个结果,占一行。
样例输入
2
6
MIN
PUSH 2
PUSH 1
MIN
POP
MIN
6
PUSH 3
MIN
PUSH 1
MIN
PUSH 2
MIN
样例输出
NULL
1
2
3
1
1
提示
巨大的输入输出量,请使用C风格的输入输出。
#include <bits/stdc++.h>
using namespace std ;
const int maxn = 100010 ;
int m;
int stack1[maxn],stack2[maxn];
int top1,top2;
char s[3 ][10 ] = {"PUSH" ,"POP" ,"MIN" };
char a[10 ];
int main () {
int T;
scanf ("%d" ,&T);
while (T--) {
top1 = 0 ;
top2 = 0 ;
scanf ("%d" ,&m);
for (int i = 0 ; i < m ; i++) {
scanf ("%s" ,a);
if (strcmp (a,s[0 ])==0 ) {
int b;
scanf ("%d" ,&b);
stack1[top1++] = b;
if (top2==0 ) {
stack2[++top2] = b;
} else if (stack2[top2] >=b) {
stack2[++top2] = b;
} else {
stack2[++top2] = stack2[top2-1 ];
}
} else if (strcmp (a,s[1 ])==0 ) {
top1--;
top2--;
} else {
if (top1==0 ) {
puts ("NULL" );
} else {
printf ("%d\n" ,stack2[top2]);
}
}
}
}
}
F题
题目描述
很多城市人口众多,政府决定在不同城市之间修建高速公路提高相互之间的交通条件。 但是由于修建费用昂贵,所以政府只要能保证所有城市都可以通过高速公路互联就可以了。 但是政府又想这些公路的容量之和尽可能的大。请你设计一下线路,看最大容量和是多少?
输入
第一行是一个整数K,表示样例数。 每个样例的第一行是两个整数N和M(2 ≤N≤1000 ;N-1 ≤M≤10000 ), N表示N个城市,其中城市代号用1 到N表示;M表示可以修建的高速公路条数。 以后的M行为每条高速公路的容量情况。 每行为三个整数X,Y,C,其中1 ≤X,Y≤N,C≤10 ^6 。
输出
每行输出一个样例的结果,为一个整数。
Sample Input
2
2 1
1 2 1
3 3
1 2 1
1 3 2
2 3 3
Sample Output
1
5
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
struct edge
{
int u,v,cost;
edge() {}
edge(int x,int y,int z)
{
u=x;
v=y;
cost=z;
}
bool operator <(const edge& a) const
{
return cost>a.cost;
}
};
edge es[20010 ];
int par[1010 ];
int n,m;
void init ()
{
for (int i=1 ;i<=n;i++) par[i]=i;
}
int find (int x)
{
return x==par[x]?x:par[x]=find(par[x]);
}
void unite (int x,int y)
{
x=find(x);
y=find(y);
if (x!=y) par[x]=y;
}
long long kruskal ()
{
sort(es,es+m);
long long sum=0 ;
int count=0 ;
for (int i=0 ;i<m;i++)
{
edge e=es[i];
if (find(e.u)!=find(e.v))
{
unite(e.u,e.v);
count++;
sum+=e.cost;
}
}
if (count!=n-1 ) sum=-1 ;
return sum;
}
int main ()
{
int a,b,c;
int t;
scanf ("%d" ,&t);
while (t--)
{
scanf ("%d%d" ,&n,&m);
init();
for (int i=0 ;i<m;i++)
{
scanf ("%d%d%d" ,&a,&b,&c);
es[i]=edge(a,b,c);
}
printf ("%lld\n" ,kruskal());
}
return 0 ;
}
G题
题目描述
给你一个序列x1,x2,…,xn,如果数对< xi,xj >,其中i < j,而xi> xj我们称之为逆序数对。 一个序列的逆序数对的数目,称为这个序列的逆序数。 比如说序列 3 1 2 ,逆序数对为 <3 ,1 >和<3 ,2 >,所以这个序列的逆序数为2 。 现在给你一个数字序列,请求其逆序数。
输入
每个样例为两行,第一行为一个整数n (n≤10 ,000 ),表示序列中数字的个数,如果n为0 ,则表示输入结束,不需要处理。 第二行是n个整数xi,0 ≤xi≤100 ,000 。输入数据保证序列中没有相同整数。
输出
每行输出一个整数,表示其序列数。
样例输入
3
3 1 2
4
1 2 3 4
0
样例输出
2
0
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std ;
const int N = 500005 ;
struct Node
{
int val;
int pos;
};
Node node[N];
int c[N], reflect[N], n;
bool cmp (const Node& a, const Node& b)
{
return a.val < b.val;
}
int lowbit (int x)
{
return x & (-x);
}
void update (int x)
{
while (x <= n)
{
c[x] += 1 ;
x += lowbit(x);
}
}
int getsum (int x)
{
int sum = 0 ;
while (x > 0 )
{
sum += c[x];
x -= lowbit(x);
}
return sum;
}
int main ()
{
while (scanf ("%d" , &n) != EOF && n)
{
for (int i = 1 ; i <= n; ++i)
{
scanf ("%d" , &node[i].val);
node[i].pos = i;
}
sort(node + 1 , node + n + 1 , cmp);
for (int i = 1 ; i <= n; ++i) reflect[node[i].pos] = i;
for (int i = 1 ; i <= n; ++i) c[i] = 0 ;
long long ans = 0 ;
for (int i = 1 ; i <= n; ++i)
{
update(reflect[i]);
ans += i - getsum(reflect[i]);
}
printf ("%lld\n" , ans);
}
return 0 ;
}
H题
题目描述
Estrella是个漂亮的小姑娘,她最喜欢吃的零食就是巧克力,但是巧克力吃多了会发胖,美貌和美食之间她必须做出艰难地选择。
Estrella有N颗巧克力,她按照喜欢的程序给巧克力排好序,并决定在M天内吃完这些巧克力。由于一颗巧克力如果不一次吃完,味道就会变坏,所以她绝对不会把一颗巧克力分开吃。但是每颗巧克力的热量并不相同,Estralla希望知道M天中每天吃的巧克力热量总和最大值。为了尽可能防止发胖,她希望这个值越小越好,请问这个值最小是多少?
输入
第一行是一个整数T (1 ≤T≤100 ),表示样例的个数。
每个样例的第一行是两个整数N,M (1 ≤M≤N≤10000 )。
每个样例的第二行是N个整数,表示每颗巧克力的热量,其值处于[1,100000] 之间。
输出
每行输出一个样例的结果。
样例输入
2
5 2
5 3 2 4 1
5 3
5 3 2 4 1
样例输出
8
5
#include <bits/stdc++.h>
using namespace std ;
const int maxn = 10001 ;
int a[maxn];
int n,m;
int check (int mid) {
int sum = 0 ;
int i_count = 0 ;
for (int i = 0 ;i < n;i++){
sum += a[i];
if (sum > mid){
sum = a[i];
i_count++;
}
if (i_count>=m){
return 0 ;
}
}
return 1 ;
}
int main () {
int T;
scanf ("%d" ,&T);
while (T--){
scanf ("%d%d" ,&n,&m);
int Max = -1 ;
int sum = 0 ;
for (int i = 0 ;i < n;i++){
scanf ("%d" ,&a[i]);
sum += a[i];
Max = max(Max,a[i]);
}
int low = Max;
int high = sum;
int mid;
int ans = 999999 ;
while (low<=high){
int mid = (low + high)/2 ;
if (check(mid)){
ans = min(ans,mid);
high = mid - 1 ;
}
else low = mid + 1 ;
}
printf ("%d\n" ,ans);
}
return 0 ;
}
I题
题目描述
5 的二进制是101 ,13 的二进制是1101 ,所以在二进制上,5 是13 的后缀。Lisa获得了一个长长的正整数列表,她想知道在列表中每一个数是列表中多少个其他数的后缀?
输入
第一行是一个整数N,1 ≤N≤100000 ,表示整数的个数。 以后N行,每行一个正整数,每个都可以使用一个32 位int 表示,而且所有的数都是唯一的。
输出
每个整数对应的结果输出一行,
样例输入
5
5
13
1
2
3
样例输出
1
0
3
0
0
#include <bits/stdc++.h>
using namespace std ;
const int maxnode = 100005 *32 ;
const int si = 2 ;
struct trie {
int ch[maxnode][si];
int num[maxnode];
int sz ;
void clear () {
sz = 1 ;
memset (ch[0 ],0 ,sizeof (ch[0 ]));
memset (num,0 ,sizeof (num));
}
void insert (int x) {
int u = 0 ;
int n = 32 ;
for (int i = 0 ; i < n&&x;i++){
if (!ch[u][x%2 ]){
memset (ch[sz],0 ,sizeof (ch[sz]));
num[sz] = 0 ;
ch[u][x%2 ] = sz++;
}
u = ch[u][x%2 ];
num[u]++;
x/=2 ;
}
}
int find (int x) {
int u = 0 ;
int n = 32 ;
for (int i = 0 ;i < n&&x;i++){
u = ch[u][x%2 ];
x /=2 ;
}
return num[u];
}
};
trie t;
int arr[maxnode/32 ];
int main () {
int n;
while (~scanf ("%d" ,&n)){
t.clear();
for (int i = 0 ;i < n;i++){
scanf ("%d" ,&arr[i]);
t.insert(arr[i]);
}
for (int i = 0 ;i < n;i++){
printf ("%d\n" ,t.find(arr[i])-1 );
}
}
return 0 ;
}
J题
Description
题目描述
N (3 ≤N≤1 ,000 )个城市(编号从1 ~N),M (N-1 ≤M≤10 ,000 )条公路连接这些城市,每条公路都是双向通车的。 你想从1 号城市出发,到达N号城市,期间你希望通过按顺序经过K (0 ≤K≤3 )个指定的城市(这K+2 个城市只允许达到1 次),求最短的里程。
输入
存在多个样例。 每个样例的第一行是三个整数N,M,K。如果N,M,K为0 ,则表示输入结束。 以后是M行表示M条公路,每行三个整数x (1 ≤x≤N),y (1 ≤y≤N),c (1 ≤c≤1 ,000 ),表示城市x与城市y之间有一条距离为c的公路。输入保证任意两座城市之间至少存在一条路。然后的一行包含K个城市的序号,序号属于[2,N-1] 。
输出
每行输出一个样例的结果,为一个整数。如果不存在这样的方案,输出“Impossible”。
样例输入
3 3 1
1 2 3
2 3 4
1 3 2
2
0 0 0
样例输出
7
#include <cstdio>
#include <cstring>
#define inf 99999999
using namespace std ;
int n,m,k,mmap[1100 ][1100 ],c[20 ],dis[1100 ],vis[1100 ];
void dij (int x,int y)
{
int i,mmin,pos,j;
memset (vis,0 ,sizeof (vis));
for (i=1 ;i<=n;i++)
dis[i]=mmap[x][i];
for (i=0 ;i<=k+1 ;i++)
{
if (c[i]!=x&&c[i]!=y)
vis[c[i]]=1 ;
}
for (i=2 ;i<=n;i++)
{
mmin=inf;
for (j=1 ;j<=n;j++)
{
if (vis[j]==0 &&dis[j]<mmin)
{
mmin=dis[j];
pos=j;
}
}
vis[pos]=1 ;
if (mmin>=inf) break ;
for (j=1 ;j<=n;j++)
{
if (vis[j]==0 &&dis[pos]+mmap[pos][j]<dis[j])
dis[j]=dis[pos]+mmap[pos][j];
}
}
}
int main ()
{
int i,j;
while (scanf ("%d%d%d" ,&n,&m,&k)!=EOF&&(n!=0 ||m!=0 ||k!=0 ))
{
for (i=1 ;i<=n;i++)
for (j=1 ;j<=n;j++)
mmap[i][j]=inf;
for (i=1 ;i<=n;i++)
mmap[i][i]=0 ;
for (i=1 ;i<=m;i++)
{
int aa,bb,cc;
scanf ("%d%d%d" ,&aa,&bb,&cc);
if (cc<mmap[aa][bb])
mmap[aa][bb]=mmap[bb][aa]=cc;
}
c[0 ]=1 ;
for (i=1 ;i<=k;i++)
scanf ("%d" ,&c[i]);
c[i]=n;
int ans=0 ,jud=1 ;
for (i=0 ;i<=k;i++)
{
dij(c[i],c[i+1 ]);
if (dis[c[i+1 ]]>=inf)
{
jud=0 ;
break ;
}
ans+=dis[c[i+1 ]];
}
if (jud==0 ) printf ("Impossible\n" );
else printf ("%d\n" ,ans);
}
return 0 ;
}
K题
题目描述
Eric喜欢旅行,今年暑假终于可以有几天时间出去玩了。他计划在去N个不同的城市,而且不想重复去相同的城市,最后需要回到出发的城市,他想知道怎么走可以让差旅费用降到最低? 我们把城市编号为0 ~N,Eric总从0 号城市出发。
输入
第一行是一个整数K,表示样例的个数。 每个样例的第一行为一个整数N(1 ≤N≤9 ),表示想去N个城市。以后的N行,每行N个整数Xij,第i行第j列个整数表示从城市i到城市j所需要的旅费,单次费用不超过1000。i = j 时,Xij = 0 。
输出
每行输出一个样例的结果,包括两行,第一行是差旅的总费用,第二行是3 个城市的编号序列,每个城市编号之间用一个空格隔开,表示旅行的路线,如果存在多条线路都是最少花费,请按字典序输出这些线路,每个线路一行,最多输出10 条线路。
样例输入
1
3
0 1 1 1
2 0 2 2
3 3 0 3
4 4 4 0
样例输出
10
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
#include <bits/stdc++.h>
using namespace std ;
int g[10 ][10 ], ans, T, path[111 ], p[10 ], pid, vis[10 ], n;
void dfs (int i, int cnt, int cost) {
if (cnt == n) {
if (cost+g[i][0 ] < ans) {
ans = cost + g[i][0 ];
pid = 0 ;
for (int j = 0 ; j < n; j++) path[pid++] = p[j];
} else if (cost+g[i][0 ] == ans && pid < n*10 ) for (int j = 0 ; j < n; j++) path[pid++] = p[j];
return ;
}
for (int j = 1 ; j <= n; j++) {
if (!vis[j]) {
vis[j] = true ;
p[cnt] = j;
dfs(j, cnt+1 , cost+g[i][j]);
vis[j] = false ;
}
}
}
int main () {
scanf ("%d" , &T);
while (T--) {
scanf ("%d" , &n);
for (int i = 0 ; i <= n; i++) for (int j = 0 ; j <= n; j++) scanf ("%d" , &g[i][j]);
ans = 11111 , pid = 0 ;
memset (vis, false , sizeof (vis));
dfs(0 ,0 ,0 );
printf ("%d\n" , ans);
pid = min(pid, n*10 );
for (int i = 0 ; i < pid; i += n) {
for (int j = i; j < i+n; j++) {
if (j%n) putchar (' ' );
printf ("%d" , path[j]);
}
puts ("" );
}
}
return 0 ;
}
L题
题目描述
猜数字游戏是这样的,主持人先从1 ~N个数字,随意取4 个数字,组成一个序列。 然后你猜了K次,每次你依次报4 个数字。主持人告诉你数字和位置都对的数字有x个,数字对但位置不对的数字有y个。 请问你满足这K次询问的数字序列有几个?分别是什么?
输入
有多个样例。第一行是一个整数N,(4 ≤N≤50 ),如果N为0 ,表示输入结束,这个样例不用处理。 第二行是一个整数K,(10 ≤k≤100 ),表示询问的次数。 以后的K行,每行6 个整数,前4 个表示你报的数字序列,每个数字在1 到N之间,且没有重复,最后两个整数为x和y。(0 ≤x+y≤N)
输出
每个样例按数字序列的字典序输出满足序列,每个序列占一行,每个整数之间用一个空格隔开,行末没空格。最后输出这些序列的总数。
样例输入
4
1
1 2 3 4 4 0
0
样例输出
1 2 3 4
1
#include <bits/stdc++.h>
int t[4 ], n, k, cnt, vis[55 ];
struct node {
int s[4 ], x, y;
} q[111 ];
bool judge (int t[4 ]) {
for (int p = 0 ; p < k; p++) {
int tx = 0 , ty = 0 ;
for (int i = 0 ; i < 4 ; i++)
if (q[p].s[i] == t[i]) tx++;
else for (int j = 0 ; j < 4 ; j++) if (q[p].s[i] == t[j]) ty++;
if (q[p].x != tx || q[p].y != ty) return false ;
}
return true ;
}
void dfs (int pos,int t[4 ]) {
if (pos == -1 ) {
if (judge(t)) printf ("%d %d %d %d\n" ,t[0 ], t[1 ], t[2 ], t[3 ]), cnt++;
return ;
}
for (int i = 1 ; i <= n; i++) {
if (!vis[i]) {
vis[i] = 1 ;
t[3 -pos] = i;
dfs(pos-1 , t);
vis[i] = 0 ;
}
}
}
int main () {
while (scanf ("%d" , &n), n) {
memset (vis, 0 , sizeof (vis));
scanf ("%d" , &k);
for (int i = 0 ; i < k; i++)
scanf ("%d %d %d %d %d %d" , q[i].s, q[i].s+1 , q[i].s+2 , q[i].s+3 , &q[i].x, &q[i].y);
cnt = 0 ;
dfs(3 , t);
printf ("%d\n" , cnt);
}
}
M题
题目描述
要过年了,老板准备发年终奖,老板准备根据员工的平时表现对比发放奖金,最低发888 ,每档再增加1000 块。
由于工作表现记录有点问题,可能存在矛盾的描述,所以,如果无法发放的话,则所有人,每人发888 元。
老板把这个任务交给你,希望你帮他算出一共需要给多少奖金,每人需要发多少奖金?
输入
第一行是一个整数K,表示样例的个数。 每个样例的第一行是两个整数n(1 ≤n≤10000 )和m(0 ≤m≤50000 ),分别表示员工的人数以及工作表现记录的数目,员工的编号从1 到n。
以后的m行为两个整数a 和b (1 ≤a ≠b ≤n),表示员工a 的工作表现比b 好。
输入数据保证工作表现不会有重复记录。
输出
每个样例先输出一行为奖金总数,然后再输出一行,按员工号的顺序,输出每个员工的奖金数,中间用一个空格隔开。
样例输入
2
3 2
1 2
2 3
3 2
1 2
2 1
样例输出
5664
2888 1888 888
2664
888 888 888
#include <bits/stdc++.h>
using namespace std ;
const int MAXN = 10010 ;
vector <int >G[MAXN];
int c[MAXN], n, m, salary[MAXN];
int dfs (int u) {
c[u] = -1 ;
for (int v = 0 ; v < G[u].size(); v++) {
int g = G[u][v];
if (c[g] == -1 ) return -1 ;
if (!c[g]) salary[g] = dfs(g);
if (salary[g] == -1 ) return -1 ;
if (salary[u] < salary[g]+1000 ) salary[u] = salary[g] + 1000 ;
}
c[u] = 1 ;
return salary[u];
}
bool toposort () {
memset (c, 0 , sizeof (c));
for (int u = 1 ; u <= n; u++)
if (!c[u])
if (dfs(u) == -1 )
return false ;
return true ;
}
int main () {
int T;
scanf ("%d" , &T);
while (T--) {
scanf ("%d %d" , &n, &m);
for (int i = 0 ; i <= n ; i++) {
salary[i] = 888 ;
G[i].clear();
}
for (int i = 0 ; i < m; i++) {
int u, v;
scanf ("%d %d" ,&u,&v);
G[u].push_back(v);
}
if (toposort()) {
int sum = 0 ;
for (int i = 1 ; i <= n; i++) sum += salary[i];
printf ("%d\n" , sum);
for (int i = 1 ; i <= n; i++)
printf ("%d%c" , salary[i], i == n ? '\n' : ' ' );
} else {
printf ("%d\n" , n*888 );
while (n--) {
printf ("888" );
(!n) ? puts ("" ) : putchar (' ' );
}
}
}
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· DeepSeek火爆全网,官网宕机?本地部署一个随便玩「LLM探索」
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 上周热点回顾(1.20-1.26)
· 【译】.NET 升级助手现在支持升级到集中式包管理