ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

7.1 NOI模拟赛 dp floyd

2020-07-01 21:34:36  阅读:172  来源: 互联网

标签:get int floyd long 7.1 include scanf dp define


avatar
avatar

这是一道非常垃圾的题目 且 数据范围简直迷惑选手。。

可以发现 题目中有 边权递增 边的条数 所有边权值不同 最小边权和等条件。

看起来很难做 一个想法 边权递增+边的1的权值都不相同可以想到 关系存在于边的话应该是一张DAG.

所以 可以把边化点建图 暴力建图是\(n^2\)的 采用归并排序+前缀和优化建图就是线性的了。

然后考虑在这张DAG上搞事情 发现边的条数很难做。

怎么做都需要一个dp数组\(f_{i,j}\)表示到达i此时经过的路径数为j的最小权值。

状态数很多 尽管转移可以拓扑排序 那么总复杂度为\(Qnm\)过不了

尽管建立除了DAG但是边的条数还是很难解决。

容易想到状态\(f_{i,j,k}\)表示i到j经过k条边的最小值。

这道题迷惑的一点是 这个状态是\(1e8\) 我以为过不了所以就一直在研究怎么在DAG上做。。

其实这个状态在开\(o2\)的情况下表现非常优秀 可以通过。

根据这道题启示我以后\(1e8~2e8\)的复杂度 大胆莽。

考虑转移 由于要求边权要求递增所以可以一条边一条边往里面插入。

实际上只需要更新以这条路径为终点即可。复杂度\(mn^2\)

但是这道题数据还是很良心的 我在DAG上跑dfs就有90了。

code bf:
//#include<bits\stdc++.h>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 1000000000
#define ldb long double
#define pb push_back
#define put_(x) printf("%d ",x);
#define get(x) x=read()
#define gt(x) scanf("%d",&x)
#define gi(x) scanf("%lf",&x)
#define put(x) printf("%d\n",x)
#define putl(x) printf("%lld\n",x)
#define gc(a) scanf("%s",a+1)
#define rep(p,n,i) for(RE int i=p;i<=n;++i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define fep(n,p,i) for(RE int i=n;i>=p;--i)
#define vep(p,n,i) for(RE int i=p;i<n;++i)
#define pii pair<int,int>
#define mk make_pair
#define RE register
#define P 1000000007
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define uint unsigned long long
#define ui unsigned
#define EPS 1e-8
#define sq sqrt
#define mod 998244353
#define S second
#define F first
#define op(x) t[x].op
#define d(x) t[x].d
#define Set(a,v) memset(a,v,sizeof(a))
using namespace std;
char buf[1<<15],*fs,*ft;
inline char getc()
{
    return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
}
inline int read()
{
    RE int x=0,f=1;RE char ch=getc();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
    return x*f;
}
const int MAXN=5010<<1,maxn=155;
int n,m,len,Q,id,mark,ans;
int s[MAXN],c[MAXN];
int lin[MAXN],ver[MAXN],nex[MAXN];
vector<pii>g[maxn],w[maxn];
struct wy{int x,y;int id;}t[MAXN];
inline void add(int x,int y)
{
	ver[++len]=y;
	nex[len]=lin[x];
	lin[x]=len;
}
inline void dfs(int x,int res,int v)
{
	if(v>=ans)return;
	if(t[x].y==mark){ans=v;return;}
	if(!res)return;
	for(int i=lin[x];i;i=nex[i])dfs(ver[i],res-s[ver[i]],v+c[ver[i]]);
}
int main()
{
	freopen("ha.in","r",stdin);
	freopen("ha.out","w",stdout);
	get(n);get(m);get(Q);
	rep(1,m,i)
	{
		int get(x),get(y),get(z);
		t[i]=(wy){x,y,z};
		g[x].pb(mk(z,i));//起点.
		w[y].pb(mk(z,i));//终点.
		s[i]=1;c[i]=z;
	}
	id=m;
	//以边化点.
	rep(1,n,i)
	{
		sort(g[i].begin(),g[i].end());
		sort(w[i].begin(),w[i].end());
		//归并建图.
		int k1=g[i].size()-1;
		int k2=w[i].size()-1;
		++id;
		for(int k=1;k<=(int)(g[i].size()+w[i].size());++k)
		{
			if(k1==-1)
			{
				add(w[i][k2].S,id);
				--k2;continue;
			}
			if(k2==-1){--k1;continue;}
			if(w[i][k2].F<g[i][k1].F)add(id,g[i][k1].S),--k1;
			else
			{
				add(w[i][k2].S,id);
				++id;add(id,id-1);--k2;
			}
		}
	}
	rep(1,Q,i)
	{
		int get(a),get(b),get(C);
		if(a==b){puts("0");continue;}
		if(!C){puts("-1");continue;}
		ans=INF;mark=b;
		vep(0,g[a].size(),j)dfs(g[a][j].S,C-1,c[g[a][j].S]);
		put(ans==INF?-1:ans);
	}
	return 0;
}
code sol:
//#include<bits\stdc++.h>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 1000000000
#define ldb long double
#define pb push_back
#define put_(x) printf("%d ",x);
#define get(x) x=read()
#define gt(x) scanf("%d",&x)
#define gi(x) scanf("%lf",&x)
#define put(x) printf("%d\n",x)
#define putl(x) printf("%lld\n",x)
#define gc(a) scanf("%s",a+1)
#define rep(p,n,i) for(RE int i=p;i<=n;++i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define fep(n,p,i) for(RE int i=n;i>=p;--i)
#define vep(p,n,i) for(RE int i=p;i<n;++i)
#define pii pair<int,int>
#define mk make_pair
#define RE register
#define P 1000000007
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define uint unsigned long long
#define ui unsigned
#define EPS 1e-8
#define sq sqrt
#define mod 998244353
#define S second
#define F first
#define op(x) t[x].op
#define d(x) t[x].d
#define Set(a,v) memset(a,v,sizeof(a))
using namespace std;
char buf[1<<15],*fs,*ft;
inline char getc()
{
    return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
}
inline int read()
{
    RE int x=0,f=1;RE char ch=getc();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
    return x*f;
}
const int MAXN=5010,maxn=155;
int n,m,len,Q,id,mark,ans;
struct wy{int x,y,z;}t[MAXN];
int f[maxn][maxn][maxn];//f[i][j][k]表示由i到j经过了<=k条边的最短路.
inline int cmp(wy a,wy b){return a.z<b.z;}
int main()
{
	freopen("1.in","r",stdin);
	//freopen("2.out","w",stdout);
	get(n);get(m);get(Q);
	rep(1,m,i)
	{
		int get(x),get(y),get(z);
		t[i]=(wy){x,y,z};
	}
	memset(f,0x3f,sizeof(f));
	sort(t+1,t+1+m,cmp);
	rep(1,n,i)rep(0,n,k)f[i][i][k]=0;
	rep(1,m,j)
	{
		rep(1,n,i)
		{
			rep(1,n,k)
			{
				f[i][t[j].y][k]=min(f[i][t[j].y][k],f[i][t[j].x][k-1]+t[j].z);
			}
		}
	}
	rep(1,Q,i)
	{
		int get(x),get(y),get(z);
		put(f[x][y][min(z,n)]>=INF?-1:f[x][y][min(z,n)]);
	}
	return 0;
}

标签:get,int,floyd,long,7.1,include,scanf,dp,define
来源: https://www.cnblogs.com/chdy/p/13221681.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有