zoukankan      html  css  js  c++  java
  • 洛谷 P1606 [USACO07FEB]荷叶塘Lilypad Pond【spfa】

    和bzoj同名题不一样!
    起点和水点向花费一个荷花能到的第一个点连一条边权为1的有向边,然后跑计数spfa即可

    #include<iostream>
    #include<cstdio>
    #include<queue>
    using namespace std;
    const int N=35,dx[]={-1,-1,1,1,-2,-2,2,2},dy[]={-2,2,-2,2,-1,1,-1,1};
    int n,m,a[N][N],id[N][N],tot,h[N*N],cnt,s,t,dis[N*N],vis[N][N],ti;
    long long b[N*N];
    bool v[N*N];
    struct qwe
    {
    	int ne,to;
    }e[500005];
    void add(int u,int v)
    {//cerr<<u<<" "<<v<<endl;
    	cnt++;
    	e[cnt].ne=h[u];
    	e[cnt].to=v;
    	h[u]=cnt;
    }
    inline bool ok(int x,int y)
    {
    	return x>=1&&x<=n&&y>=1&&y<=m&&a[x][y]!=2&&vis[x][y]!=ti;
    }
    void dfs(int u,int x,int y,int f)
    {//cerr<<u<<"  "<<x<<" "<<y<<endl;
    	vis[x][y]=ti;
    	if((a[x][y]==4||a[x][y]==0)&&!f)
    	{
    		add(u,id[x][y]);
    		// add(id[x][y],u);
    		return;
    	}
    	for(int i=0;i<8;i++)
    		if(ok(x+dx[i],y+dy[i]))
    			dfs(u,x+dx[i],y+dy[i],0);
    }
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=m;j++)
    		{
    			scanf("%d",&a[i][j]);
    			id[i][j]=++tot;
    			if(a[i][j]==3)
    				s=id[i][j];
    			if(a[i][j]==4)
    				t=id[i][j];
    		}
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=m;j++)
    			if(a[i][j]!=2&&a[i][j]!=1)
    				ti++,dfs(id[i][j],i,j,1);
    	queue<int>q;
    	for(int i=1;i<=tot;i++)
    		dis[i]=1e9;
    	dis[s]=0;
    	b[s]=1;
    	v[s]=1;
    	q.push(s);
    	while(!q.empty())
    	{
    		int u=q.front();
    		q.pop();
    		v[u]=0;
    		for(int i=h[u];i;i=e[i].ne)
    		{
    			if(dis[e[i].to]>dis[u]+1)
    			{
    				dis[e[i].to]=dis[u]+1;
    				b[e[i].to]=b[u];
    				if(!v[e[i].to])
    				{
    					v[e[i].to]=1;
    					q.push(e[i].to);
    				}
    			}
    			else if(dis[e[i].to]==dis[u]+1)
    			{
    				b[e[i].to]+=b[u];
    				if(!v[e[i].to])
    				{
    					v[e[i].to]=1;
    					q.push(e[i].to);
    				}
    			}
    		}
    	}
    	if(dis[t]==1e9)
    		puts("-1");
    	else
    		printf("%d
    %lld
    ",dis[t]-1,b[t]);
    	return 0;
    }
    
  • 相关阅读:
    如何在Eclipse中显示行号
    最值得听的100首英文歌
    ffmpeg示例一:源码
    编码解码中常用术语二
    ffmpeg.c(ffmpeg.exe)调试笔记一
    Debug ffmpeg.c & ffmpeg_g.exe in Ubuntu with Eclipse
    ubuntu下编译ffmpeg with libx264
    利用ffmpeg切割与合并视频(一)调用ffmpeg程序直接切割
    VMWare安装Ubuntu 12.10无法开启虚拟机的Unity Mode模式
    Atitit.基于dsl的methodinvoker
  • 原文地址:https://www.cnblogs.com/lokiii/p/9571012.html
Copyright © 2011-2022 走看看