【比賽】高一下二調

wlesq發表於2024-03-31

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
*/

相關文章