【题解】最短路径四题

来源:互联网 发布:网络基础知识ppt 编辑:程序博客网 时间:2024/06/10 02:31
【题解】最短路径四题 - 李kuandui - 神殇KD灬度阡陌

【分析】
这题就是一道普通的dfs,只不过方向要乘一个数而已......
经过分析,如果一个点找到了在dfs里找到了两次就是会形成一个环~,所以数据又小,直接搜吧!
要注意bfs好像很难写,反正我是不会......
【例程】

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;

char zifu;
int r,c,ans;
int ch[52][52];
bool bo[52][52];
int dx[]={-1,0,1,0},dy[]={0,1,0,-1};

void dfs(int x,int y,int now)
{
//printf("(%d,%d)\n",x,y);
if(!bo[x][y])
{
printf("-1\n");
exit(0);
}
if(ans<now)
ans=now;
for(int i=0;i<4;++i)
{
int nx=x+ch[x][y]*dx[i];
int ny=y+ch[x][y]*dy[i];
if(nx<=r&&nx>=1&&ny<=c&&ny>=1&&ch[nx][ny]!=666)
{
bo[x][y]=false;
dfs(nx,ny,now+1);
bo[x][y]=true;
}
}
}

int main()
{
freopen("board.in","r",stdin);
freopen("board.out","w",stdout);

memset(bo,true,sizeof(bo));
scanf("%d%d",&r,&c);
for(int i=1;i<=r;++i)
for(int j=1;j<=c;++j)
{
cin>>zifu;
if(zifu=='H')
ch[i][j]=666;
else
ch[i][j]=(zifu-'0');
}
dfs(1,1,1);
printf("%d\n",ans);
return 0;
}


 【题解】最短路径四题 - 李kuandui - 神殇KD灬度阡陌
【分析】
水题......最小生成树......只是找要添加的最大的边......

【例程】

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,k,ans,all,ttt,z;
int lon;
int fa[10001];
struct hehe
{
int l,a,b;
};
hehe num[1000001];
int findf(int x)
{
if(x==fa[x])return x;
return fa[x]=findf(fa[x]);
}
int cmp(hehe c,hehe d)
{
return c.l<d.l;
}
int main()
{
freopen("outofhay.in","r",stdin);
freopen("outofhay.out","w",stdout);

scanf("%d%d",&n,&k);
for(int i=1;i<=n;++i)
fa[i]=i;
for(int j=0;j<k;++j)
{
int a,b;
scanf("%d%d",&a,&b);
scanf("%d",&lon);
num[j].l=lon;
num[j].a=a;
num[j].b=b;
}
sort(num+0,num+k,cmp);
for(int i=0;i<k;++i)
{
int ka=findf(num[i].a);
int kb=findf(num[i].b);
if(ka!=kb)
{
fa[ka]=kb;
if(ans<num[i].l)
ans=num[i].l;
}
}
printf("%d\n",ans);
return 0;
}

【题解】最短路径四题 - 李kuandui - 神殇KD灬度阡陌

【分析】
看到最小转弯次数就想到BFS,而这个转弯次数不一定是第一次到就是最小的,所以可以想到SPFA的做法。
这里的难点在于处理是否转弯,我的处理方法是记录某一点是从哪一点得到的,然后在找这点扩展的新一点时,判断新一点与这一点的上一点是否在对角方向上。是就加一。其实是很容易理解的......
 【题解】最短路径四题 - 李kuandui - 神殇KD灬度阡陌
 
 就像这样,判断方法是abs(lx-nx)==1 && abs(ly-ny)==1
呵呵,第一次做时把==1打到了abs里面......然后就自我崩溃了好久......
【例程】

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;

int n,endx,endy,begx,begy;
char ch[102][102];
int lastw[102][102][3];
int head,tail;
int mapp[102][102];
int a[]={0,1,0,-1},b[]={1,0,-1,0};

struct obs
{
int x,y,turn;
};
obs d[1000000];

int main()
{
freopen("obscrs.in","r",stdin);
freopen("obscrs.out","w",stdout);

memset(mapp,127,sizeof(mapp));
memset(ch,'x',sizeof(ch));
scanf("%d",&n);
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
{
cin>>ch[i][j];
if(ch[i][j]=='A')
{
begx=i;begy=j;
d[0].x=i;d[0].y=j;
d[0].turn=0;
}
if(ch[i][j]=='B')
{
endx=i;
endy=j;
}
}
mapp[begx][begy]=0;
lastw[begx][begy][1]=begx;
lastw[begx][begy][2]=begy;
while(head<=tail)
{
int xx=d[head].x;
int yy=d[head].y;
int tt=d[head].turn;
for(int i=0;i<4;++i)
{
int nx=xx+a[i];
int ny=yy+b[i];
int nt=tt;
if(ch[nx][ny]=='x')
continue;
if( abs(nx-lastw[xx][yy][1])==1 && abs(ny-lastw[xx][yy][2])==1 )
nt++;
if(nt<mapp[nx][ny])
{
++tail;
mapp[nx][ny]=nt;
d[tail].x=nx;
d[tail].y=ny;
d[tail].turn=nt;
lastw[nx][ny][1]=xx;
lastw[nx][ny][2]=yy;
}
}
++head;
}
printf("%d\n",mapp[endx][endy]);
return 0;
}

【题解】最短路径四题 - 李kuandui - 神殇KD灬度阡陌

【分析】
==============以下言论仅代表qt个人立场==============
不会做,看例程根本看不懂......
==============以下言论仅代表qt个人立场==============
好吧我也不会- -

【例程】

#include<iostream>
#include<cstdio>
using namespace std ;
int F,N,M,W,cnt;
struct xx
{
int a,b,v;
};
xx e[100001];
bool flag,use[505];
int que[505],dis[505];
void ins(int u,int v,int w)
{
cnt++;
e[cnt].b=v;
e[cnt].a=que[u];
que[u]=cnt;
e[cnt].v=w;
}
void insert(int u,int v,int w)
{
ins(u,v,w);
ins(v,u,w);
}
void spfa(int x)
{
use[x]=1;
for (int i=que[x];i;i=e[i].a)
if (e[i].v+dis[x]<dis[e[i].b])
{
if (use[e[i].b])
{
flag=true;
return ;
}
else
{
dis[e[i].b]=e[i].v+dis[x];
spfa(e[i].b);
}
}
use[x]=false;
}
bool jud()
{
for (int i=1;i<=N;i++)
dis[i]=use[i]=0;
flag=0;
for (int i=1;i<=N;i++)
{
spfa(i);
if (flag)
return true;
}
return 0;
}
int main()
{
freopen("wormholes.in","r",stdin);
freopen("wormholes.out","w",stdout);

cin>>F;
for (int i=0;i<F;i++)
{
cnt=0;
memset(que,0,sizeof que);
cin>>N>>M>>W;
int u,v,w;
for (int i=1;i<=M;i++)
{
cin>>u>>v>>w;
insert(u,v,w);
}
for (int i=1;i<=W;i++)
{
cin>>u>>v>>w;
ins(u,v,-w);
}
if (jud()) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}


 
0 0
原创粉丝点击