24.2.11周报(第四周) (floyd)

星期一:

牛客寒假训练营2,打的一般,会做的都做了,但做了的也都是一眼能做的.

星期二:

补题:

思路:用的dij,貌似dp也行

下标1到n,超过需要模时,可以减一,模n,再加一

ve[i].push_back({b[j],(i+a[j]-1)%n+1});

因为优先队列用的PII所以爆int了,以后注意

代码如下:

ll n;
int m,k;
int a[1010],b[1010];
vector<PII>ve[5050];
bool vi[5050];
ll dis[5050];
void dij(){
	priority_queue<PII,vector<PII>,greater<PII>>pq;//pair<ll,ll>
	for(int i=0;i<5010;i++) dis[i]=LLONG_MAX;
	dis[k]=0;
	pq.push({0,k});
	while(pq.size()){
		auto [d,t]=pq.top(); pq.pop();
		if(vi[t]) continue;
		vi[t]=1;
		for(auto [x,y]:ve[t]){
			if(x+dis[t]<dis[y]){
				dis[y]=x+dis[t];
				pq.push({dis[y],y});
			}
		}
	}
}
void solve(){
	cin >> n >> m >> k;
	for(int i=1;i<=m;i++){
		cin >> a[i] >> b[i];
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			ve[i].push_back({b[j],(i+a[j]-1)%n+1});
		}
	}
	dij();
	if(dis[n]==LLONG_MAX) cout << "-1\n";
	else cout << dis[n] << "\n";
	for(int i=0;i<=n;i++) ve[i].clear(),vi[i]=0;
}

星期三:

牛客训练营3,打的依托

星期四:

补补cf的题

题意:找到一个环包含最小边,输出环的遍历路径

思路:用并查集判断环,dfs找路

代码如下:

const int N=2e5+10;
const int mod=1e9+7;
ll n;
struct nod{
	int u,v,w;
}e[N];
int m;
int uu,vv,ww;
int fa[N];
bool vi[N];
vector<PII>ve[N];
vector<int>pa;
bool cmp1(nod a,nod b){
	return a.w>b.w;
}
int fnd(int x){
	return fa[x]==x?x:fa[x]=fnd(fa[x]);
}
int dfs(int x){
	if(x==vv) return 1;
	for(auto [v,w]:ve[x]){
		if(vi[v] || w<ww) continue;
		pa.push_back(v);
		vi[v]=1;
		if(dfs(v)) return 1;
		pa.pop_back();
	}
	return 0;
}
void solve(){
	cin >> n >> m;
	for(int i=1;i<=n;i++) fa[i]=i;
	for(int i=1;i<=m;i++){
		cin >> e[i].u >> e[i].v >> e[i].w;
	}
	sort(e+1,e+m+1,cmp1);
	for(int i=1;i<=m;i++){
		int u=e[i].u,v=e[i].v,w=e[i].w;
		ve[u].push_back({v,w}),ve[v].push_back({u,w});
		int fu=fnd(u),fv=fnd(v);
		if(fu==fv) uu=u,vv=v,ww=w;
		else fa[fu]=fv;
	}
	pa.push_back(uu);
	vi[uu]=1;
	dfs(uu);
	cout << ww << " " << pa.size() << "\n";
	for(auto i:pa) cout << i << " ";
	cout << "\n";
	for(int i=1;i<=n;i++) ve[i].clear(),vi[i]=0;
	pa.clear();
}

round 923(div3) 压台的dp

题意:自行理解

思路:dp [ i ][ j ][ k ]表示考虑到 a[ i ]时左数第一个没涂色的和从i往右数第一个没涂色的,n3做法

代码如下:

const int N=2e5+10;
const int mod=1e9+7;
ll n;
int a[110];
int dp1[110][110],dp2[110][110];
void solve(){
	cin >> n;
	for(int i=1;i<=n;i++){
		cin >> a[i];
	}
	for(int i=0;i<=n+1;i++){
		for(int j=0;j<=n+1;j++)
			dp1[i][j]=dp2[i][j]=1e9;
	}
	dp1[1][1]=0;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n+1;j++){
			for(int k=max(i,j);k<=n+1;k++){
				dp2[j][k+(k==i)]=min(dp1[j][k],dp2[j][k+(k==i)]);
				int le=max(1,i-a[i]+1);
				if(le<=j){
					dp2[k+(k==i)][k+(k==i)]=min(dp1[j][k]+1,dp2[k+(k==i)][k+(k==i)]);
				}
				int ri=min(n,1ll*i+a[i]-1);
				if(ri>=k){
					if(j>=i){
						dp2[ri+1][ri+1]=min(dp1[j][k]+1,dp2[ri+1][ri+1]);
					}else{
						dp2[j][ri+1]=min(dp1[j][k]+1,dp2[j][ri+1]);
					}
				}
			}
		}
		for(int j=0;j<=n+1;j++){                    //滚动
			for(int k=0;k<=n+1;k++)
				dp1[j][k]=dp2[j][k],dp2[j][k]=1e9;
		}
	}
	cout << dp1[n+1][n+1] << "\n";
}

星期五:

玩了一天文明6,种田,爽 !

星期六:

回老家,去亲戚家吃了两顿饭

写个floyd板子

void floyd(){
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(i==j) dp[i][j]=0;
			else dp[i][j]=1e9;
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++)
			for(int k=1;k<=n;k++)
				dp[j][k]=min(dp[i][j]+dp[i][k],dp[j][k]);
	}
}

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值