列表

详情


NC17875. 字符路径

描述

给一个含n个点m条边的有向无环图(允许重边,点用1到n的整数表示),每条边上有一个字符,问图上有几条路径满足路径上经过的边上的字符组成的的字符串去掉空格后以大写字母开头,句号 '.' 结尾,中间都是小写字母,小写字母可以为0个。

输入描述

第一行两个整数n,m
接下来m行,每行两个整数a,b和一个字符c,表示一条起点为a,终点为b的边,边上的字符是c
1 ≤ n, m ≤ 50000
1 ≤ a < b ≤ n
c可以是大小写字母、句号 '.' 或空格(方便起见用 '_' 表示空格)

输出描述

输出一个整数,表示答案对232取模的结果

示例1

输入:

6 11
1 2 A
1 2 _
3 4 _
2 4 B
2 3 a
2 3 _
2 4 b
4 5 .
3 5 .
2 5 .
5 6 _

输出:

16

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 23ms, 内存消耗: 6104K, 提交时间: 2018-08-18 18:33:52

#include<bits/stdc++.h>
#define maxn 50010
using namespace std;
struct Edge
{
	int to;
	char c;
};
vector<Edge> G[maxn];
bool vis[maxn];
int p[maxn],g[maxn],f[maxn];
void slove(int x)
{
	if(vis[x])
		return;
	vis[x]=1;
	p[x]=1;
	int y;
	for(int i=0;i<G[x].size();i++)
	{
		y=G[x][i].to;
		slove(y);
		if(G[x][i].c=='_') f[x]+=f[y],p[x]+=p[y],g[x]+=g[y];
		if(G[x][i].c=='.') g[x]+=p[y];
		if(G[x][i].c>='a'&&G[x][i].c<='z') g[x]+=g[y];
		if(G[x][i].c>='A'&&G[x][i].c<='Z') f[x]+=g[y];
	}
}
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	while(m--)
	{
		int a,b;
		char c;
		scanf("%d %d %c",&a,&b,&c);
		Edge e;
		e.to=b;
		e.c=c;
		G[a].push_back(e);
	}
	memset(vis,0,sizeof(vis));
	for(int i=1;i<=n;i++)
	{
		slove(i);
	}
	int ans=0;
	for(int i=1;i<=n;i++)
		ans+=f[i];
	printf("%u\n",ans);


	return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 28ms, 内存消耗: 1996K, 提交时间: 2018-08-17 19:46:41

#include<bits/stdc++.h>
using namespace std;
#define MAXN 50005
int h[MAXN],ne[MAXN],p[MAXN],n,m,i,j,in[MAXN],f[MAXN][3],ans,q[MAXN],he,ta;
char w[MAXN],c[10];
int main()
{
	scanf("%d%d",&n,&m);
	for(i=1;i<=m;i++)
	{
		scanf("%d%d%s",&j,p+i,c);
		w[i]=c[0];
		ne[i]=h[j];
		h[j]=i;
		in[p[i]]++;
	}
	for(i=1;i<=n;i++)if(!in[i])q[ta++]=i;
	while(he!=ta)
	{
		i=q[he++];
		ans+=f[i][2];
		f[i][0]++;
		for(j=h[i];j;j=ne[j])
		{
			if(w[j]=='.')f[p[j]][2]+=f[i][1];
			else if(w[j]>='A'&&w[j]<='Z')f[p[j]][1]+=f[i][0];
			else
			{
				f[p[j]][1]+=f[i][1];
				if(w[j]=='_')
				{
					f[p[j]][0]+=f[i][0];
					f[p[j]][2]+=f[i][2];
				}
			}
			if(!(--in[p[j]]))q[ta++]=p[j];
		}
	}
	cout<<(unsigned)(ans)<<endl;
	return 0;
}

上一题