Powered by:AB_IN 局外人
忘了有比赛了,赛后就先补三个题吧。
有三个做法,第一反应还是 b f s bfs bfs,需要都跑一遍,所以就不用 v i s vis vis标记了。
#include
using namespace std;
int x2[4]={0,0,-1,1};
int y2[4]={1,-1,0,0};
const int inf=0x3f3f3f3f;
struct sa
{
int x;
int y;
int step;
};
queue<sa>q;
int a[1010][1010],dis[1010][1010];
int n;
int bfs(int x,int y)
{
int ans=inf;
q.push({x,y,a[x][y]});
while(!q.empty()){
sa tmp;
tmp=q.front();
q.pop();
int x3=tmp.x;
int y3=tmp.y;
if(x3==n&&y3==n)
ans=min(ans,tmp.step);
for(int i=0;i<4;i++){
int x4=x3+x2[i];
int y4=y3+y2[i];
if(x4>=1 && x4<=n && y4>=1 && y4<=n && a[x4][y4]!=0)
{
int d=tmp.step+a[x4][y4];
if(d<dis[x4][y4]){
dis[x4][y4]=d;
q.push({x4,y4,d});
}
}
}
}
return ans;
}
int ans=inf;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
scanf("%d",&a[i][j]);
dis[i][j]=inf;
}
}
if(!a[1][1]||!a[n][n])
printf("0");
else{
ans=bfs(1,1);
if(ans==inf){
printf("0");
}
else{
printf("%d\n",ans);
}
}
return 0;
}
d f s dfs dfs
#include
using namespace std;
int x2[4]={0,0,-1,1};
int y2[4]={1,-1,0,0};
const int inf=0x3f3f3f;
int a[1010][1010],vis[1010][1010];
int n,ans=inf;
void dfs(int x,int y,int dis){
if(x==n&&y==n){
ans=min(ans,dis);
return;
}
if(dis>=ans)return;
for(int i=0;i<4;i++){
int x3=x+x2[i];
int y3=y+y2[i];
if(x3<1||x3>n||y3<1||y3>n||a[x3][y3]==0||vis[x3][y3])
continue;
vis[x3][y3]=1;
dfs(x3,y3,dis+a[x3][y3]);
vis[x3][y3]=0;
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
scanf("%d",&a[i][j]);
}
}
if(!a[1][1]||!a[n][n])
printf("0");
else{
dfs(1, 1, a[1][1]);
if(ans==inf) printf("0");
else printf("%d",ans);
}
return 0;
}
D i j k s t r a Dijkstra Dijkstra
#include
using namespace std;
namespace IO{
char ibuf[1<<21],*ip=ibuf,*ip_=ibuf;
char obuf[1<<21],*op=obuf,*op_=obuf+(1<<21);
inline char gc(){
if(ip!=ip_)return *ip++;
ip=ibuf;ip_=ip+fread(ibuf,1,1<<21,stdin);
return ip==ip_?EOF:*ip++;
}
inline void pc(char c){
if(op==op_)fwrite(obuf,1,1<<21,stdout),op=obuf;
*op++=c;
}
inline int read(){
register int x=0,ch=gc(),w=1;
for(;ch<'0'||ch>'9';ch=gc())if(ch=='-')w=-1;
for(;ch>='0'&&ch<='9';ch=gc())x=x*10+ch-48;
return w*x;
}
template<class I>
inline void write(I x){
if(x<0)pc('-'),x=-x;
if(x>9)write(x/10);pc(x%10+'0');
}
class flusher_{
public:
~flusher_(){if(op!=obuf)fwrite(obuf,1,op-obuf,stdout);}
}IO_flusher;
}
using namespace IO;
const int maxn=1e6+10;
const int inf=0x3f3f3f3f;
struct sa{
int dis;
int pos;
};
bool operator <(const sa &a,const sa &b) { return a.dis>b.dis; }
priority_queue<sa>q;
struct Edge
{
int to, w, next;
}edge[maxn];
int head[maxn];
int cnt;
void add_edge(int u, int v, int w)
{
edge[cnt].to = v;
edge[cnt].w = w;
edge[cnt].next = head[u];
head[u] = cnt++;
}
int dis[maxn];
bool vis[maxn];
int n,m,s,u,v,w;
void dijkstra(int s,int v){
memset(vis,0,sizeof(vis));
memset(dis,0x3f,sizeof(dis));
dis[s]=v;
q.push( (sa) {0,s});
while(!q.empty())
{
sa ns=q.top();
q.pop();
int x=ns.pos;
if(vis[x]) continue;
vis[x]=1;
for(int i=head[x]; i!=-1 ; i=edge[i].next)
{
if(dis[edge[i].to]>dis[x]+edge[i].w)
{
dis[edge[i].to]=dis[x]+edge[i].w;
q.push( (sa) {dis[edge[i].to],edge[i].to});
}
}
}
}
int a[110][110];
int x2[4]={0,0,-1,1};
int y2[4]={1,-1,0,0};
int main()
{
n=read();
memset(head,-1,sizeof(head));
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
a[i][j]=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
if(a[i][j]){
for(int h=0;h<4;h++){
int x3=i+x2[h];
int y3=j+y2[h];
if(x3>=1 && x3<=n && y3>=1 && y3<=n && a[x3][y3]){
add_edge(i*n+j, x3*n+y3, a[x3][y3]);
}
}
}
}
dijkstra(n+1,a[1][1]);
if(dis[n*n+n]==inf) printf("0");
else printf("%d",dis[n*n+n]);
return 0;
}
签到。
l=set()
cnt=0
for _ in range(int(input())):
s=input()
if s not in l:
cnt+=1
l.add(s)
if s=="younik":
print(cnt)
break
次短路!!! 顾名思义就是第二短的路
边可以重复走!
#include
using namespace std;
namespace IO{
char ibuf[1<<21],*ip=ibuf,*ip_=ibuf;
char obuf[1<<21],*op=obuf,*op_=obuf+(1<<21);
inline char gc(){
if(ip!=ip_)return *ip++;
ip=ibuf;ip_=ip+fread(ibuf,1,1<<21,stdin);
return ip==ip_?EOF:*ip++;
}
inline void pc(char c){
if(op==op_)fwrite(obuf,1,1<<21,stdout),op=obuf;
*op++=c;
}
inline int read(){
register int x=0,ch=gc(),w=1;
for(;ch<'0'||ch>'9';ch=gc())if(ch=='-')w=-1;
for(;ch>='0'&&ch<='9';ch=gc())x=x*10+ch-48;
return w*x;
}
template<class I>
inline void write(I x){
if(x<0)pc('-'),x=-x;
if(x>9)write(x/10);pc(x%10+'0');
}
class flusher_{
public:
~flusher_(){if(op!=obuf)fwrite(obuf,1,op-obuf,stdout);}
}IO_flusher;
}
using namespace IO;
const int maxn=1e6+10;
const int inf=0x3f3f3f3f;
struct sa{
int dis;
int pos;
};
bool operator <(const sa &a,const sa &b) { return a.dis>b.dis; }
priority_queue<sa>q;
struct Edge
{
int u, v, w, next;
}edge[maxn<<2];
int head[maxn];
int cnt;
void add_edge(int u, int v, int w)
{
edge[cnt].u = u;
edge[cnt].v = v;
edge[cnt].w = w;
edge[cnt].next = head[u];
head[u] = cnt++;
}
int dis1[maxn],dis2[maxn];
bool vis[maxn];
int n,m,s,u,v,w;
void dij(int s,int v,int d[]){
memset(vis,0,sizeof(vis));
for (int i=0;i<=n;i++) d[i] = inf;
d[s]=v;
q.push( (sa) {0,s});
while(!q.empty())
{
sa ns=q.top();
q.pop();
int x=ns.pos;
if(vis[x]) continue;
vis[x]=1;
for(int i=head[x]; i!=-1 ; i=edge[i].next)
{
int to=edge[i].v;
int dd=d[x]+edge[i].w;
if(d[to]>dd)
{
d[to]=dd;
q.push( (sa) {d[to],to});
}
}
}
}
int main()
{
memset(head,-1,sizeof(head));
cin>>n>>m;
for(int i=1; i<=m; i++){
cin>>u>>v>>w;
u++;v++;//题目是0到n-1,++之后就成了1到n了。
add_edge(u,v,w);
add_edge(v,u,w);
//不用(v+n,u+n,w+n),因为cnt一直在++,统计每个边,顺下去即可。
}
dij(1,0,dis1);//从1开始跑最短路
dij(n,0,dis2);//从n开始跑最短路
int ans1=dis1[n],ans2=inf,min_d=inf;
for(int i=1;i<=cnt;i++){
u=edge[i].u; v=edge[i].v; w=edge[i].w;
if((dis1[u]+w) +dis2[v]> ans1)
//dis1[u]意思就是从1->u的最短路
//dis2[v]意思就是从n->v的最短路
//中间就还差了一个u->v的w
//如果大于最短路,那么就先取最小值
ans2= min(ans2,(dis1[u]+w) +dis2[v]);
if((dis1[u]+w) +dis2[v]== ans1)
//如果这个就是最短路,那么遍历它的每一条边,求出所有边的最小值
min_d=min(min_d,w);
}
cout<<min(ans2,ans1+min_d*2);
return 0;
}
完结。