【2019HDU暑期多校第一場泛做】

題目是按通過量做的,所以題號可能不太對。

1.Vacation

這種問題一定不能思考的太複雜,不要把自己繞進去。
我們就簡單的將其分成兩類:
(1) 前面沒車堵我。
(2) 前面全部都堵我。

對於第一種情況,沒車堵我,那麼顯然就是s[0]/v[0]。
重點關注第二種情況,前面所有的車都堵我。
思考了五秒鐘以後我們發現,前面所有的車都堵我是啥意思,就是第一輛車最慢唄。
那麼答案是什麼呢?就是(s[n]+sum[n])/v[n]。因爲n是第一輛車。
這樣我們就可以觀察出來,我的速度是受別人的限制的。
所以我們枚舉每一輛前面的車,看看它會不會堵我就行了。

複雜度O(n)

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+7;
double l[maxn],s[maxn],v[maxn];
double sum[maxn];
int n;
int main()
{
	while(~scanf("%d",&n))
	{
		for(int i=0;i<=n;i++) scanf("%lf",l+i);
		for(int i=0;i<=n;i++) scanf("%lf",s+i);
		for(int i=0;i<=n;i++) scanf("%lf",v+i);
		double ans = s[0]/v[0];
		sum[0] = 0;
		for(int i=1;i<=n;i++)
		{
			sum[i] = sum[i-1] + l[i];
			ans = max(ans,(s[i]+sum[i])/v[i]);
		}
		printf("%.6lf\n",ans);
	}
	return 0;
}

2.Path
很明顯先求一個最短路,然後在最短路的邊上求最小割就完事了。

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 2e4+7;
struct node
{
	int to;
	int cost;
};
vector<node> V[maxn];
int n,m;
int x[maxn],y[maxn],z[maxn];
ll dis[maxn];
struct edge
{
	int to;
	ll cap;
	int rev;
};
vector<edge> G[maxn];
int depth[maxn],arc[maxn];
void add_edge(int from,int to,ll cost)
{
	G[from].push_back((edge){to,cost,G[to].size()});
	G[to].push_back((edge){from,0,G[from].size()-1});
}
void bfs(int s)
{
	queue<int> q;
	memset(depth,-1,sizeof(depth));
	depth[s] = 0;
	q.push(s);
	while(!q.empty())
	{
		int v = q.front();
		q.pop();
		for(int i=0;i<G[v].size();i++)
		{
			edge &e = G[v][i];
			if(e.cap>0 && depth[e.to]<0)
			{
				depth[e.to] = depth[v]+1;
				q.push(e.to);
			}
		}
	}
}
ll dfs(int v,int t,ll f)
{
	if(v==t) return f;
	for(int &i=arc[v];i<G[v].size();i++)
	{
		edge &e = G[v][i];
		if(e.cap>0 && depth[e.to]==depth[v]+1)
		{
			ll d = dfs(e.to,t,min(f,e.cap));
			if(d>0)
			{
				e.cap -= d;
				G[e.to][e.rev].cap += d;
				return d;
			}
		}
	}
	return 0;
}
ll dinic(int s,int t)
{
	ll flow = 0;
	while(true)
	{
		bfs(s);
		if(depth[t]<0) return flow;
		memset(arc,0,sizeof(arc));
		ll f;
		while((f=dfs(s,t,INF))>0)
		{
			flow += f;
		}
	}
}
void dijkstra(int s)
{
	struct edge
	{
		int now;
		int cost;
		bool operator<(const edge &rhs)const
		{
			return cost>rhs.cost;
		}
	};
	memset(dis,INF,sizeof(dis));
	dis[s] = 0;
	priority_queue<edge> q;
	q.push({s,dis[s]});
	while(!q.empty())
	{
		edge tmp = q.top();
		q.pop();
		for(int i=0;i<V[tmp.now].size();i++)
		{
			int v = V[tmp.now][i].to;
			if(dis[v]>dis[tmp.now]+V[tmp.now][i].cost)
			{
				dis[v] = dis[tmp.now] + V[tmp.now][i].cost;
				q.push({v,dis[v]});
			}
		}
	}
}
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		memset(G,0,sizeof(G));
		memset(V,0,sizeof(V));
		scanf("%d%d",&n,&m);
		for(int i=0;i<m;i++)
		{
			scanf("%d%d%d",x+i,y+i,z+i);
			V[x[i]].push_back({y[i],z[i]});
		}
		dijkstra(1);
		for(int i=1;i<=n;i++)
		{
			for(int j=0;j<V[i].size();j++)
			{
				int v = V[i][j].to;
				if(dis[v]==dis[i]+V[i][j].cost) add_edge(i,v,V[i][j].cost);
			}
		}
		printf("%d\n",dinic(1,n));
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章