POJ 2570

我在Codeforces上做过一道类似的题目,当时是纯DFS暴力解决的。做这题时以为还是一样,结果TLE了。然后用floyd来做,但是我是用三维数组的方式的conj[i][j][k]代表i和j直接边都是k是否为一条通路。结果还是TLE,看其他人的题解,发现竟然是二进制。conj[i][j]代表i和j之间的状态,状态中二进制的第k位为1的话代表i和j之间存在一条所有边都是k的通路。其实我一开始的做法和二进制的道理是一样的,但是估计是位运算的速度比普通运算的速度要快,所以常数比较小,于是这样才可以。

#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<cmath>
#include<stack>
#include<set>
using namespace std;

const int maxn=205;
int conj[maxn][maxn];
char str[30];
int main()
{
	int n;
	while(scanf("%d",&n)!=EOF)
	{
		if(0==n) break;
		memset(conj,0,sizeof(conj));
		int a,b;
		while(scanf("%d%d",&a,&b)!=EOF)
		{
			if(0==a&&0==b) break;
			scanf("%s",str);
			int len=strlen(str);
			for(int i=0;i<len;i++)
			{
				char tem=str[i];
				conj[a][b]|=(1<<(tem-'a'));
			}
		}

		//floyd
		for(int k=1;k<=n;k++)
		{
			for(int i=1;i<=n;i++)
			{
				for(int j=1;j<=n;j++)
				{
					conj[i][j]|=(conj[i][k]&conj[k][j]);
				}
			}
		}

		while(scanf("%d%d",&a,&b)!=EOF)
		{
			bool flag=false;
			if(0==a&&0==b) break;
			for(int i=0;i<26;i++)
			{
				if(conj[a][b]&(1<<i)) { printf("%c",char('a'+i));flag=true;}
			}
			if(!flag) printf("-");
			printf("\n");
		}
		printf("\n");
	}
}
时间: 2024-12-08 22:01:24

POJ 2570的相关文章

POJ 2570 线段树

Potted Flower Time Limit: 2000 MS Memory Limit: 65536 KB 64-bit integer IO format: %I64d , %I64u Java class name: Main [Submit] [Status] [Discuss] Description The little cat takes over the management of a new park. There is a large circular statue in

Poj 2570 Fiber Network Floyd思想处理

感觉非常有意思,也不难想. f[i][j] |= f[i][k] & f[k][j] #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <

POJ 2570(floyd)

http://poj.org/problem?id=2570 题意:在海底有一些网络节点.每个节点之间都是通过光缆相连接的.不过这些光缆可能是不同公司的. 现在某个公司想从a点发送消息到b点,问哪个公司可以提供这个服务. 首先输入一共有几个公司. 其次输入的是a,b两点之间的光缆是由哪几个公司提供的.0 0结束. 然后询问a,b之间是否可以有公司提供服务,有就输出那个公司,没有的话就输出- 思路:当我看到这个题,我也不知道具体怎么去操作,然后百度了一下,发现了一个人的思路很好.对于a-z这些字母

POJ 2570 Fiber Network(最短路 二进制处理)

题目翻译 一些公司决定搭建一个更快的网络,称为"光纤网".他们已经在全世界建立了许多站点,这 些站点的作用类似于路由器.不幸的是,这些公司在关于站点之间的接线问题上存在争论,这样"光纤网"项目就被迫终止了,留下的是每个公司自己在某些站点之间铺设的线路. 现在,Internet 服务供应商,当想从站点 A传送数据到站点 B,就感到困惑了,到底哪个公司 能够提供必要的连接.请帮助供应商回答他们的查询,查询所有可以提供从站点 A到站定 B的线 路连接的公司. 输入描述:

POJ 2570 Fiber Network

最短路变形. 题意是说不同的点之间有不同的公司建立了不同连接. 询问 A,B之间如果存在通路,有那些公司. 我用bool  g[][][26] 来表示26个字母.然后Floyd, G++就超时.C++ 就AC了. 然后看别人代码才知道还有位运算--ORZ... 自己的代码:C++ AC.813ms #include<cstdio> #include<cstring> #include<string> #include<queue> #include<a

poj 2570 Fiber Network (Floyd)

Fiber Network Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3107   Accepted: 1427 Description Several startup companies have decided to build a better Internet, called the "FiberNet". They have already installed many nodes that ac

ZOJ 1967 POJ 2570 Fiber Network

枚举起点和公司,每次用DFS跑一遍图,预处理出所有的答案.询问的时候很快就能得到答案. #include<cstdio> #include<cmath> #include<cstring> #include<vector> #include<algorithm> using namespace std; int jz[300][300][30]; int ans[300][300][30]; int flag[300]; vector<in

poj 2570 Fiber Network(floyd)

#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int mp[30][250][250]; int main() { int n,u,v,i,j,l,k,p,f; char s[1024]; while(~scanf("%d",&n)) { if(n==0) break; memset(mp,0,sizeof(mp)); while(~

poj 2570 floyd+二进制

二进制真的是个神奇的东西! 类似floyd求传递闭包,这里g[i][j]表示i点到j点的状态(即符合条件的公司的集合). 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const int N = 201; 7 const int M = 31; 8 int g[N][N]; 9 int n; 10 11 int main () 12 {