搜索

做题笔记 - yeshubo -


发布时间: 2022-11-24 23:14:00    浏览次数:79 次

才想到开这个坑。之前的背包和区间 DP 有空可能会补几题。

背包

区间 DP

图论(最短路/最小生成树/拓扑排序)

A CF601A The Two Routes

一定有一种交通工具存在一条路径连接 \(1,n\),于是对另一种交通工具跑最短路即可。

点击查看代码
#include <bits/stdc++.h>
//#define int long long
using namespace std;
int n,m,x,y,i,j,k,dis[405][405],sum;
signed main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>n>>m;
	memset(dis,0x3f,sizeof(dis));
	for (i=1;i<=m;i++){
		cin>>x>>y,dis[x][y]=1,dis[y][x]=1;
		sum+=((x==1 && y==n) || (x==n && y==1));
	}
	if (sum!=0)
		for (i=1;i<=n;i++)
			for (j=1;j<=n;j++)
				if (dis[i][j]==1) dis[i][j]=dis[0][0];
				else dis[i][j]=1;
	for (k=1;k<=n;k++)
		for (i=1;i<=n;i++)
			for (j=1;j<=n;j++)
				dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
	return cout<<(dis[1][n]==dis[0][0]?-1:dis[1][n]),0;
}

B CF59E Shortest Path

BFS 的同时记录上一个经过的点即可。记录前驱的时候记录边,不是点。

启示:BFS 等算法同样是解决最短路问题的有效手段。

点击查看代码
#include <bits/stdc++.h>
//#define int long long
using namespace std;
int n,m,T,i,x,y,z;
struct Edge{
	int to,nex,dis,pre,id;
}e[40005];
int h[3005],cnt;
void add_edge(int x,int y){
	e[++cnt].to=y,e[cnt].nex=h[x],e[cnt].id=cnt,h[x]=cnt;
}
struct node{
	int pre,now,step,id;
} ;
queue <node> Q;
map <pair<pair<int,int> ,int> ,bool> c;
void go(int x){
	if (e[x].pre) go(e[x].pre);
	cout<<' '<<e[x].to;
}
signed main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>n>>m>>T;
	for (i=1;i<=m;i++)
		cin>>x>>y,add_edge(x,y),add_edge(y,x);
	for (i=1;i<=T;i++)
		cin>>x>>y>>z,c[make_pair(make_pair(x,y),z)]=true;
	Q.push(node{0,1,0,0});//pre now step id
	while (!Q.empty()){
		node x=Q.front();
		Q.pop();
		if (x.now==n){
			cout<<x.step<<'\n'<<1;
			return go(x.id),0;
		}
		for (i=h[x.now]; i; i=e[i].nex){
			if (c[make_pair(make_pair(x.pre,x.now),e[i].to)]) continue;
			if (e[i].dis) continue;
			e[i].dis=x.step+1,e[i].pre=x.id;
			Q.push((node){x.now,e[i].to,x.step+1,i});
		}
	}
	return cout<<-1,0;
}

C CF1196F K-th Path

\(k\le400\),从这方面入手,取最短的 \(k\) 条边,至多 \(2k\) 个点做最短路,可以证明答案一定在其中。

点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
struct Edge{int x,y,z;} e[200005];
bool cmp(Edge x,Edge y){return x.z<y.z;}
priority_queue <int,vector<int>,greater<int> > Q;
int n,m,k,i,j,tot,f[805][805],rnk[200005],vis[200005];
signed main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>n>>m>>k;
	for (i=1;i<=m;i++) cin>>e[i].x>>e[i].y>>e[i].z;
	if (m>k) sort (e+1,e+1+m,cmp);
	for (i=1;i<=min(m,k);i++) vis[e[i].x]=1,vis[e[i].y]=1;
	for (i=1;i<=n;i++)
		if (vis[i]) rnk[i]=(++tot);
	memset(f,0x3f,sizeof(f));
	for (i=1;i<=min(m,k);i++)
		f[rnk[e[i].x]][rnk[e[i].y]]=f[rnk[e[i].y]][rnk[e[i].x]]=e[i].z;
	for (int _=1;_<=tot;_++)
		for (i=1;i<=tot;i++)
			for (j=1;j<=tot;j++)
				f[i][j]=min(f[i][j],f[i][_]+f[_][j]);
	for (i=1;i<=tot;i++)
		for (j=i+1;j<=tot;j++)
			Q.push(f[i][j]);
	for (i=1;i<k;i++) Q.pop();
	return cout<<Q.top(),0;
}

D CF1307D Cow and Fields

周六补。

免责声明 做题笔记 - yeshubo - ,资源类别:文本, 浏览次数:79 次, 文件大小:-- , 由本站蜘蛛搜索收录2022-11-24 11:14:00。此页面由程序自动采集,只作交流和学习使用,本站不储存任何资源文件,如有侵权内容请联系我们举报删除, 感谢您对本站的支持。 原文链接:https://www.cnblogs.com/yeshubo/p/16916529.html