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 ;
}

 

你可能感兴趣的:(NetWork)