Codeforces Round #374 (div.2)遗憾题合集

时间:2023-03-10 03:23:15
Codeforces Round #374 (div.2)遗憾题合集

C.Journey

读错题目了。。。不是无向图,结果建错图了(喵第4样例是变成无向就会有环的那种图)

并且这题因为要求路径点尽可能多

其实可以规约为限定路径长的拓扑排序,不一定要用最短路做

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0),eps=1e-;
void File()
{
freopen("D:\\in.txt","r",stdin);
freopen("D:\\out.txt","w",stdout);
}
template <class T>
inline void read(T &x)
{
char c = getchar();
x = ;
while(!isdigit(c)) c = getchar();
while(isdigit(c)) { x = x * + c - ''; c = getchar(); }
} const int INF=0x7fffffff;
const int maxn=;
int dp[maxn][maxn];
struct Edge
{
int v,nx; int w;
}e[maxn];
int h[maxn],sz,r[maxn];
int n,m,T;
queue<int>Q;
int pre[maxn][maxn]; void add(int u,int v,LL w)
{
e[sz].v=v; e[sz].w=w;
e[sz].nx=h[u]; h[u]=sz++;
} int main()
{
scanf("%d%d%d",&n,&m,&T); for(int i=;i<=n;i++)
{
h[i]=-;
for(int j=;j<=n;j++)
{
dp[i][j]=INF;
pre[i][j]=-;
}
} for(int i=;i<=m;i++)
{
int u,v; LL w; scanf("%d%d%d",&u,&v,&w);
add(u,v,w); r[v]++;
} dp[][]=;
for(int i=;i<=n;i++) if(r[i]==) Q.push(i);
bool flag=;
while(!Q.empty())
{
int top=Q.front(); Q.pop();
if(top==) flag=;
if(flag==)
{
for(int i=h[top];i!=-;i=e[i].nx)
{
int to=e[i].v;
r[to]--;
if(r[to]==) Q.push(to);
}
continue;
}
for(int i=h[top];i!=-;i=e[i].nx)
{
int to=e[i].v;
for(int j=;j<=n;j++)
{
if(dp[top][j-]==INF) continue;
if(dp[top][j-]+e[i].w>T) continue;
if(dp[top][j-]+e[i].w>=dp[to][j]) continue; pre[to][j]=(top-)*n+j--;
dp[to][j]=dp[top][j-]+e[i].w;
}
r[to]--;
if(r[to]==) Q.push(to);
}
} int sum;
for(int i=;i<=n;i++) if(dp[n][i]<=T) sum=i; cout<<sum<<endl;
int nowx=n,nowy=sum; stack<int>S;
while()
{
S.push(nowx);
int tx,ty;
tx=pre[nowx][nowy]/n; tx++;
ty=pre[nowx][nowy]%n; ty++;
if(pre[nowx][nowy]==-) break;
nowx=tx; nowy=ty;
}
while(!S.empty())
{
cout<<S.top()<<" "; S.pop();
} return ;
}

D.Maxim and Array

没时间做。。。被第2、3题耽误了

试算了一下发现并不复杂。。。每次取绝对值最小的数(使其余值的乘积绝对值最大)这样对其加减时,总乘积变化也就最大

太多数了,直接乘会爆long long,直接判断负数个数(总乘积的正负性),以此判断要加要减

#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <iostream>
#include <queue>
#include <math.h>
using namespace std; const int N = + ;
typedef long long ll; ll aabs(ll x) {return x< ? -x : x;} struct node
{
ll num;
int id;
bool operator < (const node & temp) const
{
return aabs(num) > aabs(temp.num);
}
}; ll a[N];
ll n,k,x; int main()
{
cin >> n >> k >> x;
int sign = ;
priority_queue<node> Q;
for(int i=;i<=n;i++)
{
scanf("%I64d",a+i);
if(a[i] < ) sign = -sign;
Q.push((node){a[i],i});
}
while(k--)
{
node temp = Q.top();Q.pop();
if(a[temp.id] < )
{
if(sign == -) a[temp.id] -= x;
else a[temp.id] += x;
if(a[temp.id] >= ) sign = -sign;
}
else
{
if(sign == -) a[temp.id] += x;
else a[temp.id] -= x;
if(a[temp.id] < ) sign = -sign;
}
Q.push((node){a[temp.id],temp.id});
}
for(int i=;i<=n;i++)
{
printf("%I64d%c",a[i],i==n?'\n':' ');
}
}

E.Road to Home