POJ 2570 Fiber Network (传递闭包)
题意:给定n个城市之间的有向图,每条边是以字母标示的,输出在每条可行线路u->v中,其所经过的每一段线路的相同的字母。
思路:由于两点之间有多条线路,所以想到了对每个字母进行floyd,最后集中输出,然后华丽的TLE了.......后来知道可以用位运算优化,汗......没想出来.....然后就可以AC了。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <memory.h>
#include <cmath>
#include <bitset>
#include <queue>
#include <vector>
using namespace std;
const int BORDER = (1<<20)-1;
const int MAXSIZE = 37;
const int MAXN = 505;
const int INF = 1000000000;
#define CLR(x,y) memset(x,y,sizeof(x))
#define ADD(x) x=((x+1)&BORDER)
#define IN(x) scanf("%d",&x)
#define OUT(x) printf("%d\n",x)
#define MIN(m,v) (m)<(v)?(m):(v)
#define MAX(m,v) (m)>(v)?(m):(v)
#define ABS(x) ((x)>0?(x):-(x))
int map[MAXN][MAXN];
int n,m;
bool mark[MAXN];
int init()
{
CLR(map,0);
CLR(mark,0);
return 0;
}
int input()
{
int i,u,v,k,len;
char str[30];
for( ; ; )
{
scanf("%d%d",&u,&v);
if(!u || !v)
break;
scanf("%s",str);
len = strlen(str);
for(i = 0; i < len; ++i)
map[u][v] |= (1<<(str[i]-'a'));
}
return 0;
}
int floyd()
{
int i,j,k,tmp;
for(k = 1; k <= n; ++k)
for(i = 1; i <= n; ++i)
for(j = 1; j <= n; ++j)
map[i][j] |= (map[i][k] & map[k][j]);
return 0;
}
int work()
{
int i,j,tmp,u,v;
bool tag;
floyd();
for( ; ; )
{
scanf("%d%d",&u,&v);
if(!u || !v)
break;
tag =false;
for(i = 0; i < 26; ++i)
if(map[u][v] & (1<<i))
{
tag = true;
printf("%c",'a'+i);
}
if(tag)
printf("\n");
else
printf("-\n");
}
printf("\n");
return 0;
}
int main()
{
while(IN(n))
{
if(!n)
break;
init();
input();
work();
}
return 0;
TLE code:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <memory.h>
#include <cmath>
#include <bitset>
#include <queue>
#include <vector>
using namespace std;
const int BORDER = (1<<20)-1;
const int MAXSIZE = 37;
const int MAXN = 505;
const int INF = 1000000000;
#define CLR(x,y) memset(x,y,sizeof(x))
#define ADD(x) x=((x+1)&BORDER)
#define IN(x) scanf("%d",&x)
#define OUT(x) printf("%d\n",x)
#define MIN(m,v) (m)<(v)?(m):(v)
#define MAX(m,v) (m)>(v)?(m):(v)
#define ABS(x) ((x)>0?(x):-(x))
typedef struct{
bool alp[26];
}Node;
Node map[MAXN][MAXN];
int n,m;
bool mark[MAXN];
int init()
{
CLR(map,0);
CLR(mark,0);
return 0;
}
int input()
{
int i,u,v,k,len;
char str[30];
for( ; ; )
{
scanf("%d%d",&u,&v);
if(!u || !v)
break;
scanf("%s",str);
len = strlen(str);
for(i = 0; i < len; ++i)
{
map[u][v].alp[str[i]-'a'] = true;
mark[str[i]-'a'] = true;
}
}
return 0;
}
int floyd(const int& ind)
{
int i,j,k,tmp;
for(k = 1; k <= n; ++k)
for(i = 1; i <= n; ++i)
for(j = 1; j <= n; ++j)
map[i][j].alp[ind] |= (map[i][k].alp[ind]&map[k][j].alp[ind]);
return 0;
}
int work()
{
int i,j,tmp,u,v;
bool tag;
for(i = 0; i < 26; ++i)
{
if(!mark[i])
continue;
floyd(i);
}
for( ; ; )
{
scanf("%d%d",&u,&v);
if(!u || !v)
break;
tag =false;
for(i = 0; i < 26; ++i)
if(map[u][v].alp[i])
{
tag = true;
printf("%c",'a'+i);
}
if(tag)
printf("\n");
else
printf("-\n");
}
return 0;
}
int main()
{
while(IN(n))
{
if(!n)
break;
init();
input();
work();
}
return 0;
}