拓扑排序/DP【洛谷P2883】 [USACO07MAR]牛交通Cow Traffic

P2883 [USACO07MAR]牛交通Cow Traffic

随着牛的数量增加,农场的道路的拥挤现象十分严重,特别是在每天晚上的挤奶时间。为了解决这个问题,FJ决定研究这个问题,以能找到导致拥堵现象的瓶颈所在。

牧场共有M条单向道路,每条道路连接着两个不同的交叉路口,为了方便研究,FJ将这些交叉路口编号为1..N,而牛圈位于交叉路口N。任意一条单向道路的方向一定是是从编号低的路口到编号高的路口,因此农场中不会有环型路径。同时,可能存在某两个交叉路口不止一条单向道路径连接的情况。

在挤奶时间到来的时候,奶牛们开始从各自的放牧地点回到牛圈。放牧地点是指那些没有道路连接进来的路口(入度为0的顶点)。

现在请你帮助fj通过计算从放牧点到达牛圈的路径数目来找到最繁忙的道路(答案保证是不超过32位整数)。

思维固化了。

看到这题直接套上P1685 游览的板子。

才得60分。

再读题(看题解),发现这题会有多个起点,多个终点。

那么对于多个终点,只能去n,所以还要从n建反边跑一边拓扑排序,这样一条边的贡献就是\(g(u)*f(v)\)

好像我用了最笨的方法跑两边拓扑排序。

code:

#include <iostream>
#include <cstdio>
#include <queue>

using namespace std;

const int wx=500017;

inline int read(){
	int sum=0,f=1; char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
	while(ch>='0'&&ch<='9'){sum=(sum<<1)+(sum<<3)+ch-'0'; ch=getchar();}
	return sum*f;
}

int n,m,ans;
int num,tot;
int g[wx],head[wx],h[wx],f[wx];
int in[wx],out[wx],in2[wx],out2[wx];

struct e{
	int nxt,to;
}edge[wx*2];

void add(int from,int to){
	edge[++num].nxt=head[from];
	edge[num].to=to;
	head[from]=num;
}

struct ee{
	int nxt,to;
}e[wx*2];

void ADD(int from,int to){
	e[++tot].nxt=h[from];
	e[tot].to=to;
	h[from]=tot;
}

queue<int > q;

void bfs1(){
	for(int i=1;i<=n;i++)if(!in[i])g[i]=1,q.push(i);
	while(q.size()){
		int u=q.front(); q.pop();
		for(int i=head[u];i;i=edge[i].nxt){
			int v=edge[i].to;
			g[v]+=g[u];
			in[v]--;
			if(!in[v]){
				q.push(v);
			}
		}
	}
}

void bfs2(){
	for(int i=1;i<=n;i++)if(!in2[i])f[i]=1,q.push(i);
	while(q.size()){
		int u=q.front(); q.pop();
		for(int i=h[u];i;i=e[i].nxt){
			int v=e[i].to;
			f[v]+=f[u];
			in2[v]--;
			if(!in2[v])q.push(v);
		}
	}
	for(int u=1;u<=n;u++){
		for(int i=head[u];i;i=edge[i].nxt){
			int v=edge[i].to;
			ans=max(ans,g[u]*f[v]);
		}
	}
}

int main(){
	n=read(); m=read();
	for(int i=1;i<=m;i++){
		int x,y; 
		x=read(); y=read();
		if(x>y)swap(x,y);
		add(x,y); in[y]++; out[x]++;
		ADD(y,x); in2[x]++; out2[y]++;
	}
	bfs1();
	bfs2();
	printf("%d\n",ans);
	return 0;
}
posted @ 2018-10-18 17:16  _王小呆  阅读(191)  评论(0编辑  收藏  举报