ACM 图论 UVALive 5966
Blade and Sword
暴力 SPFA 写了8个小时才AC呀o(╯□╰)o
本题正解”双向“搜索,分两次从起点终点开始
其中后面那个代码是暴力,接近超时
Memory: 0 KB | Time: 102 MS | |
Language: C++ 4.5.3 | Result: Accepted |
/*
* Author: vawait
* Created Time: 2014/8/3 12:46:19
* File Name: test.cpp
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<stack>
#include<ctime>
using namespace std;
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define red(i, a, b) for (int i = (a); i >= (b); --i)
#define clr( x , y ) memset(x,y,sizeof(x))
#define mp make_pair
#define pb push_back
#define x first
#define y second
#define sqr(x) ((x) * (x))
#define num( i , j ) ( ( i - 1 ) * m + j )
typedef long long lint;
int n , m , d[40010] , S , T , s , qs[80010];
int dx[] = { 0 , 0 , 1 , -1 };
int dy[] = { 1 , -1 , 0 , 0 };
vector < int > a[40010];
pair < int , int > q1[80010] , q2[80010];
char c[300][300];
void init()
{
scanf("%d%d",&n,&m);
red(i,n*m,0) a[i].clear();
s = 0;
rep(i,1,n) scanf("%s",c[i]+1);
rep(i,1,n)
rep(j,1,m) if ( c[i][j] != '#' ) {
if ( c[i][j] != '*' ) rep(k,0,3) {
int x = i + dx[k] , y = j + dy[k];
if ( x >= 1 && x <= n && y >= 1 && y <= m )
a[num( i , j )].pb( num( x , y ) );
}
if ( c[i][j] == '*' ) qs[++s] = num( i , j );
if ( c[i][j] == 'P' ) S = num( i , j );
if ( c[i][j] == 'D' ) T = num( i , j );
}
}
void work()
{
queue < int > q;
int x , y;
q.push( S );
clr( d , 1 );
d[S] = 0;
while ( !q.empty() ) {
x = q.front() ; q.pop();
red(i,a[x].size()-1,0) if ( d[y=a[x][i]] > 1000000 ) {
d[y] = d[x] + 1;
q.push( y );
}
}
rep(i,1,s) q1[i].x = d[qs[i]] , q1[i].y = i;
int ans = d[T];
q.push( T );
clr( d , 1 ); d[T] = 0;
while ( !q.empty() ) {
x = q.front() ; q.pop();
red(i,a[x].size()-1,0) if ( d[y=a[x][i]] > 1000000 ) {
d[y] = d[x] + 1;
q.push( y );
}
}
rep(i,1,s) q2[i].x = d[qs[i]] , q2[i].y = i;
if ( s ) sort( q1 + 1 , q1 + s + 1 );
if ( s ) sort( q2 + 1 , q2 + s + 1 );
red(i,min(2,s),1)
red(j,min(2,s),1) {
if ( q1[i].y != q2[j].y ) ans = min( ans , q1[i].x + 1 + q2[j].x );
else if ( s > 1 ) ans = min( ans , q1[i].x + 2 + q2[j].x );
}
if ( ans < 1000000 ) printf("%d\n",ans); else puts("impossible");
}
int main()
{
int t;
cin >> t;
rep(i,1,t) {
printf("Case %d: ",i);
init();
work();
}
return 0;
}
Memory: 0 KB | Time: 2713 MS | |
Language: C++ 4.5.3 | Result: Accepted |
/*
* Author: NICK WONG
* Created Time: 8/3/2014 14:32:53
* File Name: e.cpp
*/
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
#include<iomanip>
using namespace std;
#define out(x) cout<<#x<<": "<<x<<endl
const double eps(1e-8);
const int maxn=210;
const long long maxint=-1u>>1;
const long long maxlong=maxint*maxint;
typedef long long lint;
typedef int point[2];
struct node
{
int x,y,len,type,tele;
//node(int x=0,int y=0,int len=0,int type=0,bool tele=0):
// x(x),y(y),len(len),type(type),tele(tele) {};
};
point tele1,tele2,st,en,star[maxn*maxn],tmp[5];
char a[maxn][maxn];
int n,m,t,dis[maxn][maxn],arr[maxn][maxn],lim,tmplen[5];
queue<node> q;
const int step[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
void init()
{
star[0][0]=0;
char c;
scanf("%c",&c);
for (int i=1; i<=n; i++)
{
for (int j=1; j<=m; j++)
{
scanf("%c",&a[i][j]);
if (a[i][j]=='P') {st[0]=i; st[1]=j;} else
if (a[i][j]=='D') {en[0]=i; en[1]=j;} //else
//if (a[i][j]=='*') {star[++star[0][0]][0]=i; star[star[0][0]][1]=j; }
}
scanf("%c",&c);
}
for (int i=0; i<=n+1; i++) a[i][0]=a[i][m+1]='#';
for (int j=0; j<=m+1; j++) a[0][j]=a[n+1][j]='#';
}
void spfa()
{
int mytype;
memset(dis,-1,sizeof(dis));
memset(arr,-1,sizeof(arr));
node x={st[0],st[1],0,0,0};
q.push(x); dis[st[0]][st[1]]=0;
while (q.size())
{
x=q.front(); q.pop();
if (x.type==0)
{
for (int i=0; i<=3; i++)
{
int u=x.x+step[i][0]; int v=x.y+step[i][1];
if (a[u][v]!='#' && (x.len+1<dis[u][v] || dis[u][v]<0))
{
dis[u][v]=x.len+1;
if (a[u][v]=='*') mytype=1; else mytype=0;
if (a[u][v]=='*' && (x.tele>=lim)) continue;
if (u==en[0] && v==en[1]) return;
node y={u,v,dis[u][v],mytype,x.tele};
q.push(y);
}
}
} else
if (x.type==1 && (x.tele<lim))
{
for (int i=1; i<=star[0][0]; i++)
{
int u=star[i][0]; int v=star[i][1];
if ((u==x.x && v==x.y)) continue;
if (x.len+1<arr[u][v] || arr[u][v]<0)
{
arr[u][v]=x.len+1;
node y={u,v,arr[u][v],2,x.tele+1};
q.push(y);
}
}
} else
if (x.type==2)
{
for (int i=0; i<=3; i++)
{
int u=x.x+step[i][0]; int v=x.y+step[i][1];
if (a[u][v]!='#' && a[u][v]!='*' && (x.len+1<dis[u][v] || dis[u][v]<0))
{
dis[u][v]=x.len+1;
if (a[u][v]=='*') mytype=1; else mytype=0;
node y={u,v,dis[u][v],mytype,x.tele};
if (u==en[0] && v==en[1]) return;
q.push(y);
}
}
if (x.tele<lim)
for (int i=1; i<=star[0][0]; i++)
{
int u=star[i][0]; int v=star[i][1];
if ((u==x.x && v==x.y)) continue;
if (x.len+1<arr[u][v] || arr[u][v]<0)
{
arr[u][v]=x.len+1;
node y={u,v,arr[u][v],2,x.tele+1};
q.push(y);
}
}
}
}
}
void check(int x, int y,int len)
{
dis[x][y]=1;
for (int i=0; i<=3; i++)
{
int u=x+step[i][0]; int v=y+step[i][1];
if (a[u][v]=='*')
if (len+1<tmplen[1])
{
tmplen[2]=tmplen[1];
tmp[2][0]=tmp[1][0]; tmp[2][1]=tmp[1][1];
tmplen[1]=len+1;
tmp[1][0]=u; tmp[1][1]=v;
} else
if (len+1<tmplen[2])
{
tmplen[2]=len+1;
tmp[2][0]=u; tmp[2][1]=v;
}
if (dis[u][v]==-1 && a[u][v]!='#' && a[u][v]!='*')
{
dis[u][v]=1;
check(u,v,len+1);
}
}
}
void work()
{
lim=2;
memset(dis,-1,sizeof(dis));
tmplen[1]=tmplen[2]=maxint;
check(st[0],st[1],0);
for (int i=1; i<=2; i++)
if (tmplen[i]!=maxint)
{
star[++star[0][0]][0]=tmp[i][0];
star[star[0][0]][1]=tmp[i][1];
}
memset(dis,-1,sizeof(dis));
tmplen[1]=tmplen[2]=maxint;
check(en[0],en[1],0);
for (int i=1; i<=2; i++)
if (tmplen[i]!=maxint)
{
star[++star[0][0]][0]=tmp[i][0];
star[star[0][0]][1]=tmp[i][1];
}
bool wjj=false;
for (int i=1; i<=n; i++)
for (int j=1; j<=m; j++)
{
if (wjj) break;
bool flag=true;
if (a[i][j]!='*') continue;
for (int k=1; k<=star[0][0]; k++)
{
int u=star[k][0]; int v=star[k][1];
if (u==i && v==j) flag=false;
}
if (flag)
{
star[++star[0][0]][0]=i;
star[star[0][0]][1]=j;
}
}
//if (dis[en[0]][en[1]]==-1) lim=2; else lim=1;
//near_tele(st,tele1);
//near_tele(en,tele2);
while(q.size()) q.pop();
spfa();
cout<<"Case "<<t<<": ";
if (dis[en[0]][en[1]]==-1) cout<<"impossible"<<endl; else cout<<dis[en[0]][en[1]]<<endl;
}
int main()
{
int test;
cin>>test;
for (t=1; t<=test; t++)
{
cin>>n>>m;
init();
work();
}
return 0;
}
/*void near_tele(point en,point tele)
{
tele[0]=tele[1]=0;
bool flag=false;
memset(dis,-1,sizeof(dis));
memset(arr,-1,sizeof(arr));
node x(en[0],en[1],0,0,false);
q.push(x); dis[en[0]][en[1]]=0;
while(q.size())
{
x=q.front(); q.pop();
if (flag) break;
for (int i=0; i<=3; i++)
{
int u=x.x+step[i][0]; int v=x.y+step[i][1];
if (a[u][v]!='#' && (x.len+1<dis[u][v] || dis[u][v]<0))
{
dis[u][v]=x.len+1;
if ((!flag) && a[u][v]=='*')
{
tele[0]=u; tele[1]=v;
flag=true;
}
q.push(node(u,v,dis[u][v]));
}
}
}
while(q.size())
{
q.pop();
}
}*/