T1 Candy
不说了不说了
大模拟
#include<bits/stdc++.h>
using namespace std;
#define in Read()
int in{
int i=0,f=1;char ch=0;
while(!isdigit(ch)&&ch!='-') ch=getchar();
if(ch=='-') ch=getchar(),f=-1;
while(isdigit(ch)) i=(i<<1)+(i<<3)+ch-48,ch=getchar();
return i*f;
}
const int N=1000;
int n,a[3][N],f[3][N];
void DFS(int x,int y){
if(x==2&&y==n) return;
if(x==1){
f[x+1][y]=max(f[x+1][y],f[x][y]+a[x+1][y]);
DFS(x+1,y);
}
if(y<n){
f[x][y+1]=max(f[x][y+1],f[x][y]+a[x][y+1]);
DFS(x,y+1);
}
return;
}
int main(){
freopen("candy.in","r",stdin);
freopen("candy.out","w",stdout);
n=in;
for(int i=1;i<=n;++i) a[1][i]=in;
for(int i=1;i<=n;++i) a[2][i]=in;
f[1][1]=a[1][1];
DFS(1,1);
cout<<f[2][n]<<endl;
return 0;
}
T2 Line
这题卡差分约束???
毒瘤出题人
好好练下带权并查集
听说拓扑也行
那就写拓扑了
拓排比带权并查集好些多了✌️
#include<bits/stdc++.h>
using namespace std;
#define in Read()
int in{
int i=0,f=1;char ch=0;
while(!isdigit(ch)&&ch!='-') ch=getchar();
if(ch=='-') ch=getchar(),f=-1;
while(isdigit(ch)) i=(i<<1)+(i<<3)+ch-48,ch=getchar();
return i*f;
}
const int N=2e5+5;
int n,m,deg[N];
int tot,first[N],nxt[N<<1],wei[N<<1],aim[N<<1],dis[N];
bool vis[N];
queue<int>q;
void ljb(int u,int v,int w){
++tot;
nxt[tot]=first[u];
first[u]=tot;
aim[tot]=v;
wei[tot]=w;
return;
}
bool topo(){
for(int i=1;i<=n;++i)
if(!deg[i]) q.push(i),vis[i]=true;
while(!q.empty()){
int u=q.front();q.pop();
for(int e=first[u];e;e=nxt[e]){
int v=aim[e];--deg[v];
if(dis[v]&&dis[v]!=dis[u]+wei[e]) return false;
else dis[v]=dis[u]+wei[e];
if(!deg[v]) q.push(v),vis[v]=true;
}
}
for(int i=1;i<=n;++i) if(!vis[i]) return false;
return true;
}
int main(){
n=in,m=in;
for(int i=1;i<=m;++i){
int u=in,v=in,w=in;
ljb(u,v,w);
++deg[v];
}
puts(topo()?"Yes":"No");
return 0;
}
T3 Meet
迪杰的时候记录方案
a
n
s
=
c
n
t
[
s
→
t
]
×
c
n
t
[
t
→
s
]
−
i
l
l
e
g
a
l
ans=cnt[s\to t]\times cnt[t\to s]-illegal
ans=cnt[s→t]×cnt[t→s]−illegal
其中
i
l
l
e
g
a
l
=
(
c
n
t
[
s
→
i
]
×
c
n
t
[
t
→
i
]
)
×
c
n
t
[
s
→
i
]
×
c
n
t
[
t
→
i
]
illegal=(cnt[s\to i]\times cnt[t\to i])\times cnt[s\to i]\times cnt[t\to i]
illegal=(cnt[s→i]×cnt[t→i])×cnt[s→i]×cnt[t→i]
括号内:到达这个点的总方案数
括号外:单独到这个点的方案数
都是不合法的,要乘起来
不止亿点毒瘤
#include<bits/stdc++.h>
using namespace std;
#define in Read()
int in{
int i=0, f=1;char ch=0;
while (!isdigit(ch)&&ch!='-') ch=getchar();
if (ch=='-') ch=getchar(), f=-1;
while (isdigit(ch)) i=(i<<1)+(i<<3)+ch-48, ch=getchar();
return i*f;
}
typedef long long ll;
const int N=2e5+10, mod=1e9+7;
int n, m, s, t;
int tot, first[N], nxt[N<<1], aim[N<<1], wei[N<<1];
ll dis[2][N], ans[2][N];
bool vis[2][N];
int add(int a, int b) {
return a+b>=mod?a+b-mod:a+b;
}
int dec(int a, int b) {
return a<b?a-b+mod:a-b;
}
int mul(int a, int b) {
return 1ll*a*b%mod;
}
void ljb(int u, int v, int w) {
++tot;
nxt[tot]=first[u];
first[u]=tot;
aim[tot]=v;
wei[tot]=w;
return;
}
void Dijkstra(int o, ll *dis, bool *vis, ll *ans) {
priority_queue<pair<ll, int> >q;
dis[o]=0;
q.push(make_pair(0, o));
ans[o]=1;
while (!q.empty()) {
int u=q.top().second;q.pop();
if(vis[u]) continue;
vis[u]=true;
for (int e=first[u];e;e=nxt[e]) {
int v=aim[e];
if (dis[v]>dis[u]+wei[e]) {
dis[v]=dis[u]+wei[e];
ans[v]=ans[u];
q.push(make_pair(-dis[v], v));
}
else {
if (dis[v]==dis[u]+wei[e])
ans[v]=add(ans[v], ans[u]);
}
}
}
return;
}
int main() {
int n=in, m=in, s=in, t=in;
for (int i=1;i<=m;++i) {
int u=in, v=in, w=in;
ljb(u, v, w);
ljb(v, u, w);
}
memset(dis, 0x3f, sizeof(dis));
Dijkstra(s, dis[0], vis[0], ans[0]);
Dijkstra(t, dis[1], vis[1], ans[1]);
ll sum=mul(ans[0][t], ans[1][s]);
ll len=dis[1][s];
for (int u=1;u<=n;++u) {
if (dis[0][u]==dis[1][u]&&(dis[1][u]<<1)==len)
sum=dec(sum, mul(mul(ans[0][u], ans[1][u]), mul(ans[0][u], ans[1][u])));
for (int e=first[u];e;e=nxt[e]) {
int v=aim[e];
ll d1=dis[0][u], d2=dis[1][v];
if (d1+d2+wei[e]==len&&(d1<<1)<len&&(d2<<1)<len)
sum=dec(sum, mul(mul(ans[0][u], ans[1][v]), mul(ans[0][u], ans[1][v])));
}
}
printf("%lld\n", sum);
return 0;
}