【比赛】高一下二调
史
T1
用SPFA/DIJ跑一遍,顺便标记下路径和权值,然后依次改边值遍历跑SPFA/DIJ即可
点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 250000+10;
int n,m,head[501],way[501][2],cnt,c2;int dis[501];
bool vis[501];
struct Edge
{
int from,to,w,next;
}edge2[N],edge[N],e2[1002];
bool cmp(Edge a,Edge b)
{
return a.w<b.w;
}
struct node
{
int u;int dis;
bool operator < (const node &A)const
{
return dis<A.dis;
}
};
void add(int u,int v,int w)
{
edge[++cnt].from=u;
edge[cnt].to=v;
edge[cnt].next=head[u];
edge[cnt].w=w;
head[u]=cnt;
}
bool fst=1;
int ans=INT_MAX,st,en;
void dij()
{
memset(dis,0x3f,sizeof(dis));
memset(vis,0,sizeof(vis));
priority_queue <node> q;
q.push({1,0});
// q.push({100,0});
// cout<<q.top().u<<endl;
dis[1]=0;
// cout<<"&&";
while(!q.empty())
{
int u=q.top().u;q.pop();
if(vis[u])continue;
vis[u]=1;
for(int i=head[u];i;i=edge[i].next)
{
int to=edge[i].to;
// if(to==st&&u==en&&edge[i].w==ans)edge[i].w=2*ans;
// if(to==en&&u==st&&edge[i].w==ans)edge[i].w=2*ans;
if((to==en&&u==st&&edge[i].w==ans)||(to==st&&u==en&&edge[i].w==ans))
{
if(dis[to]>dis[u]+2*ans)
{
dis[to]=dis[u]+2*ans;
q.push({to,-dis[to]});
}
}
else if(dis[to]>dis[u]+edge[i].w)
{
dis[to]=dis[u]+edge[i].w;
if(fst==1)way[to][0]=u;way[to][1]=edge[i].w;
// cout<<to<<" "<<dis[to]<<endl;
// vis[to]=0;
q.push({to,-dis[to]});
}
}
}
}
int T2;
void test()
{
for(int i=1;i<=n;i++)
cout<<dis[i]<<" ";
}
main()
{
freopen("traffic.in","r",stdin);
freopen("traffic.out","w",stdout);
scanf("%lld%lld",&n,&m);
int a,b,t;
for(int i=1;i<=m;i++)
{
scanf("%lld%lld%lld",&a,&b,&t);
add(a,b,t);add(b,a,t);
}
// cout<<T2<<endl;
// cout<<"&"<<st<<" "<<en<<" "<<ans<<endl;
dij();
int T=dis[n];
int x=n;
int tot=0;
fst=0;
while(x)
{
int u=way[x][0];
st=u;en=x;
ans=way[x][1];
dij();
// cout<<u<<" "<<ans<<" "<<dis[n]<<endl;
tot=max(tot,dis[n]-T);
// cout<<u<<" "<<x<<endl;
x=u;
}
cout<<tot;
// test();
return 0;
}
/*
5 7
1 2 10
1 3 2
3 2 16
5 3 14
3 4 6
4 2 14
4 5 4
*/
T2
二分即可
点击查看代码
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 100000+5;
int n,m;ll cla[N];
ll ans;
bool check(ll mid)
{
int tot=1;ll pos=cla[1];
for(int i=2;i<=n;i++)
{
if(cla[i]-pos>=mid)
{
tot++;
pos=cla[i];
}
}
if(tot>=m)return 1;
else return 0;
}
void fen(ll l,ll r)
{
while(l<=r)
{
ll mid=(l+r)>>1;
if(check(mid))
{
ans=mid;
l=mid+1;
}else
{
r=mid-1;
}
}
}
int main()
{
freopen("classroom.in","r",stdin);
freopen("classroom.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%lld",&cla[i]);
}
sort(cla+1,cla+n+1);
fen(1,1e10);
cout<<ans;
return 0;
}
T3
单调队列板子
点击查看代码
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 400000+5;
int n,m;ll h[N],dis[N],dis2[N];
int main()
{
freopen("post.in","r",stdin);
freopen("post.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld",&h[i]);
}
deque <ll> q;
ll ans=0;
for(int i=1;i<=n+1;i++)
{
while(!q.empty()&&h[q.back()]>h[i])
{
dis[q.back()]=i-q.back();
q.pop_back();
}
q.push_back(i);
}
while(!q.empty())q.pop_back();
for(int i=n;i>=0;i--)
{
while(!q.empty()&&h[q.back()]>h[i])
{
dis2[q.back()]=q.back()-i;
q.pop_back();
}
q.push_back(i);
}
for(int i=1;i<=n;i++)
{
// cout<<dis[i]<<" "<<dis2[i]<<endl;
ll you=i+(dis[i]-1);
ll zuo=i-(dis2[i]-1);
ans=max(ans,1ll*(you-zuo+1)*h[i]);
}
cout<<ans<<endl;
return 0;
}
/*
6
5 8 4 4 8 4
*/
T4
LCA板子,记得调用dfs_init函数
点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5+10;
int n,m,head[N],cnt;;bool vis[N];
struct Edge
{
int from,to,w,next;
}edge[N*2];
int f[N][32];int dis[N],d[N];
void add(int u,int v,int w)
{
edge[++cnt].from=u;
edge[cnt].to=v;
edge[cnt].next=head[u];
edge[cnt].w=w;
head[u]=cnt;
}
void test()
{
for(int i=1;i<=n;i++)
cout<<dis[i]<<" ";
}
void dfs(int now,int fa)
{
vis[now]=1;
f[now][0]=fa;
d[now]=d[fa]+1;
for(int i=head[now];i;i=edge[i].next)
{
int to=edge[i].to;
if(!vis[to])
{
dis[to]=dis[now]+edge[i].w;
dfs(to,now);
}
}
}
void init()
{
for(int j=1;j<32;j++)
{
for(int i=1;i<=n;i++)
{
f[i][j]=f[f[i][j-1]][j-1];
// dis[i][j]=min(dis[i][j],dis[f[i][j-1]][j-1]);
}
}
}
int lca(int x,int y)
{
if(d[x]<d[y])swap(x,y);
for(int i=31;i>=0;i--)
{
if(d[f[x][i]]>=d[y])x=f[x][i];
}
if(x==y)return x;
// for(int i=0;i<=31;i++)
for(int i=31;i>=0;i--)
{
if(f[x][i]!=f[y][i])
{
x=f[x][i];
y=f[y][i];
}
}
return f[x][0];
}
main()
{
freopen("meeting.in","r",stdin);
freopen("meeting.out","w",stdout);
scanf("%lld%lld",&n,&m);
int a,b,t;
for(int i=1;i<=m;i++)
{
scanf("%lld%lld%lld",&a,&b,&t);
add(a,b,t);add(b,a,t);
}
for(int i=1;i<=n;i++)
{
if(!vis[i])
{
dfs(i,0);
}
}
int q;
scanf("%lld",&q);
init();
for(int i=1;i<=q;i++)
{
scanf("%lld%lld",&a,&b);
int c=lca(a,b);
// cout<<c<<endl;
printf("%lld\n",dis[a]+dis[b]-2*dis[c]);
}
return 0;
}
/*
6 5
1 3 3
1 2 7
2 4 5
4 6 6
3 5 7
5
3 4
6 3
5 1
4 3
4 2
*/