bzoj3887: [Usaco2015 Jan]Grass Cownoisseur

题意:

给一个有向图,然后选一条路径起点终点都为1的路径出来,有一次机会可以沿某条边逆方向走,问最多有多少个点可以被经过?(一个点在路径中无论出现多少正整数次对答案的贡献均为1)

=>有向图我们先考虑缩点。然后观察缩点后的图可以发现新的路径中必定只有一条边是反向的才符合条件。那么我们可以联想到某道最短路的题将边反向存一遍后分别从s和t跑一跑。那么这里bfs跑一跑就行了。然后有一个坑点:这种重建图的注意es和edges不然es会在中途就被修改掉了。。。

#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
#include<queue>
#include<stack>
using namespace std;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define clr(x,c) memset(x,c,sizeof(x))
#define qwq(x) for(edge *o=head[x];o;o=o->next)
#define qaq(x) for(edge *o=hd[x];o;o=o->next)
#define TAT(x) for(edge *o=eo[x];o;o=o->next)
int read(){
	int x=0;char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) x=x*10+c-‘0‘,c=getchar();
	return x;
}
const int nmax=1e5+5;
const int inf=0x7f7f7f7f;

struct edge{
	int to;edge *next;
};edge es[nmax],edges[nmax<<1],*pt=es,*head[nmax],*hd[nmax],*eo[nmax];
void add(int u,int v){
	pt->to=v;pt->next=head[u];head[u]=pt++;
}
void adde(int u,int v){
	pt->to=v;pt->next=hd[u];hd[u]=pt++;
	pt->to=u;pt->next=eo[v];eo[v]=pt++;
}
int pre[nmax],dfs_clock=0,scc_cnt=0,sccno[nmax],sm[nmax];
stack<int>s;
int dfs(int x){
	int lowu=pre[x]=++dfs_clock;s.push(x);
	qwq(x){
		if(!pre[o->to]) lowu=min(lowu,dfs(o->to));
		else if(!sccno[o->to]) lowu=min(lowu,pre[o->to]);
	}
	if(lowu==pre[x]){
		++scc_cnt;int tc=0;
		while(1){
			int tx=s.top();s.pop();
			sccno[tx]=scc_cnt;++tc;
			if(x==tx) break;
		}
		sm[scc_cnt]=tc;
	}
	return lowu;
}

queue<int>q;bool vis[nmax];int f[nmax],g[nmax];
int test_cnt=0;
void bfs1(int x){
	q.push(x);f[x]=sm[x];int tx;clr(vis,0);
	while(!q.empty()){
		tx=q.front();q.pop();vis[tx]=0;
		qaq(tx) if(f[o->to]<f[tx]+sm[o->to]){
			f[o->to]=f[tx]+sm[o->to];
			if(!vis[o->to]) q.push(o->to),vis[o->to]=1;
		}
	}
}
void bfs2(int x){
	q.push(x);g[x]=sm[x];int tx;clr(vis,0);
	while(!q.empty()){
		tx=q.front();q.pop();vis[tx]=0;
		TAT(tx) if(g[o->to]<g[tx]+sm[o->to]){
			g[o->to]=g[tx]+sm[o->to];
			if(!vis[o->to]) q.push(o->to),vis[o->to]=1;
		}
	}
}

int main(){
	int n=read(),m=read(),u,v;
	rep(i,1,m) u=read(),v=read(),add(u,v);
	rep(i,1,n) if(!pre[i]) dfs(i);
	//rep(i,1,n) printf("%d ",sccno[i]);printf("\n");

	pt=edges;
	rep(i,1,n) qwq(i) if(sccno[i]!=sccno[o->to]) adde(sccno[i],sccno[o->to]);
	bfs1(sccno[1]);bfs2(sccno[1]);
	//rep(i,1,scc_cnt) printf("%d %d\n",f[i],g[i]);

	int ans=sm[sccno[1]];
	rep(i,1,scc_cnt) qaq(i) {
		if(g[i]&&f[o->to]) ans=max(ans,g[i]+f[o->to]-sm[sccno[1]]);
	}
	printf("%d\n",ans);return 0;
}

  

3887: [Usaco2015 Jan]Grass Cownoisseur

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 179  Solved: 92
[Submit][Status][Discuss]

Description

In an effort to better manage the grazing patterns of his cows, Farmer John has installed one-way cow paths all over his farm. The farm consists of N fields, conveniently numbered 1..N, with each one-way cow path connecting a pair of fields. For example, if a path connects from field X to field Y, then cows are allowed to travel from X to Y but not from Y to X. Bessie the cow, as we all know, enjoys eating grass from as many fields as possible. She always starts in field 1 at the beginning of the day and visits a sequence of fields, returning to field 1 at the end of the day. She tries to maximize the number of distinct fields along her route, since she gets to eat the grass in each one (if she visits a field multiple times, she only eats the grass there once). As one might imagine, Bessie is not particularly happy about the one-way restriction on FJ‘s paths, since this will likely reduce the number of distinct fields she can possibly visit along her daily route. She wonders how much grass she will be able to eat if she breaks the rules and follows up to one path in the wrong direction. Please compute the maximum number of distinct fields she can visit along a route starting and ending at field 1, where she can follow up to one path along the route in the wrong direction. Bessie can only travel backwards at most once in her journey. In particular, she cannot even take the same path backwards twice.

给一个有向图,然后选一条路径起点终点都为1的路径出来,有一次机会可以沿某条边逆方向走,问最多有多少个点可以被经过?(一个点在路径中无论出现多少正整数次对答案的贡献均为1)

Input

The first line of input contains N and M, giving the number of fields and the number of one-way paths (1 <= N, M <= 100,000). The following M lines each describe a one-way cow path. Each line contains two distinct field numbers X and Y, corresponding to a cow path from X to Y. The same cow path will never appear more than once.

Output

A single line indicating the maximum number of distinct fields Bessie

can visit along a route starting and ending at field 1, given that she can

follow at most one path along this route in the wrong direction.

Sample Input

7 10

1 2

3 1

2 5

2 4

3 7

3 5

3 6

6 5

7 2

4 7

Sample Output

6

HINT

Source

Gold&鸣谢18357

时间: 2024-10-28 14:08:30

bzoj3887: [Usaco2015 Jan]Grass Cownoisseur的相关文章

BZOJ 3887[Usaco2015 Jan]Grass Cownoisseur

题面: 3887: [Usaco2015 Jan]Grass Cownoisseur Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 237  Solved: 130[Submit][Status][Discuss] Description In an effort to better manage the grazing patterns of his cows, Farmer John has installed one-way cow pat

BZOJ 3887 Usaco2015 Jan Grass Cownoisseur Tarjan+拓扑排序

题目大意:给定一张图,从1开始随便走最后回到1,有一次机会可以反向沿着某条边走一次,求最多能经过多少个点 显然如果没有反向的机会的话答案就是1号节点所在强连通分量的大小 现在有了这个机会 那么将某条边反向后 缩点之后的图形成了一个包含1号节点所在强连通分量的环 这样才能使答案增加 将这个环从反向的边和1号节点所在强连通分量处断开 发现这个环被拆成了两条链 一条从1出发,一条指向1 因此缩点后利用拓扑排序分别求出正图和反图中1号节点所在强连通分量到每个强连通分量的最长链 然后枚举每条边反转更新答案

【tarjan+拓扑】BZOJ3887-[Usaco2015 Jan]Grass Cownoisseur

[题目大意] 给一个有向图,然后选一条路径起点终点都为1的路径出来,有一次机会可以沿某条边逆方向走,问最多有多少个点可以被经过?(一个点在路径中无论出现多少正整数次对答案的贡献均为1) [思路] 首先缩点,对于每一个联通块求出正图和反图中节点1所在的联通块到它的最长节点数.这个用拓扑排序处理一下. 枚举每一条边取反,对于边(u,v),其取反后的距离就等于dis[u所在的联通快]+dis[v所在的联通块]-dis[1所在的联通块](因为会被重复计算不要忘记减去) 我一开始非常脑抽地在想会不会发生这

洛谷 P3119 [USACO15JAN]草鉴定Grass Cownoisseur

P3119 [USACO15JAN]草鉴定Grass Cownoisseur tarjan缩点,正反spfa,枚举边,更新最大值 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define maxn 1000000 4 #define inf 0x3f3f3f3f 5 int n,m,x[maxn],y[maxn],z,num,head[maxn],head2[maxn],tim,ans,tot,dis1[maxn],dis2[maxn

3890: [Usaco2015 Jan]Meeting Time( dp )

简单的拓扑图dp.. A(i, j), B(i, j) 表示从点 i 长度为 j 的两种路径是否存在. 用bitset就行了 时间复杂度O(m) ---------------------------------------------------------------- #include<bits/stdc++.h> #define clr(x, c) memset(x, c, sizeof(x)) #define rep(i, n) for(int i = 0; i < n; ++

bzoj3886: [Usaco2015 Jan]Moovie Mooving

题意: PoPoQQQ要在电影院里呆L分钟,这段时间他要看小型电影度过.电影一共N部,每部都播放于若干段可能重叠的区间,PoPoQQQ决不会看同一部电影两次.现在问他要看最少几部电影才能度过这段时间? 注:必须看电影才能在电影院里呆着,同时一场电影可以在其播放区间内任意时间入场出场.N=20.每部电影的重复区间<=100. =>N=20.那么我们还是考虑二进制枚举.转移方程类似.时间复杂度类似.哎呀套路啊... #include<cstdio> #include<cstrin

洛谷——P3119 [USACO15JAN]草鉴定Grass Cownoisseur

P3119 [USACO15JAN]草鉴定Grass Cownoisseur 题目描述 In an effort to better manage the grazing patterns of his cows, Farmer John has installed one-way cow paths all over his farm. The farm consists of N fields, conveniently numbered 1..N, with each one-way co

线段树 BZOJ3888 [Usaco2015 Jan]Stampede

3888: [Usaco2015 Jan]Stampede Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 253  Solved: 81[Submit][Status][Discuss] Description Farmer John's N cows (1 <= N <= 50,000) appear to be stampeding along the road at the front of FJ's farm, but they are

P3119 [USACO15JAN]草鉴定Grass Cownoisseur

P3119 [USACO15JAN]草鉴定Grass Cownoisseur 题目描述 In an effort to better manage the grazing patterns of his cows, Farmer John has installed one-way cow paths all over his farm. The farm consists of N fields, conveniently numbered 1..N, with each one-way co