zoukankan      html  css  js  c++  java
  • hdu 3416 Marriage Match IV

    从城市A到B,每次都走最短路,但每条边最多走一次,能够走多少次

    曾做过一次这种题。建最短路树,跑SPFA

    值得注意的是,如果跑dij的时候不建立永久标号,会导致最短路树出错

    spfa要不停的进行松弛操作,同理不能这样建最短路树。看网上代码spfa都是正着反着跑两遍spfa,然后判断dis1[u]+dis2[v]+w==dis[B]是否成立。若成立,则u,v为最短路上的边

    把网上的和我的都交了一遍,我的更快*_*

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<vector>
    using namespace std;
    const int maxn=1008;
    const int maxm=100008;
    const int INF=0x7f7f7f7f;
    struct shit{
    	int v,w;
    	bool operator<(const shit &a)	const
    	{
    		return w>a.w;
    	}
    };
    struct fuck{
    	int u,v,cap,next;
    }edge[maxm<<2];
    vector<shit>	g[maxn];
    int dis[maxn];
    vector<int>	distree[maxn];
    bool vis[maxn];
    int head[maxn];
    int tol;
    void init()
    {
    	tol=0;
    	memset(head,-1,sizeof(head));
    }
    void addedge(int u,int v,int w)
    {
    	edge[tol].u=u;
    	edge[tol].v=v;
    	edge[tol].cap=w;
    	edge[tol].next=head[u];
    	head[u]=tol++;
    	edge[tol].u=v;
    	edge[tol].v=u;
    	edge[tol].cap=0;
    	edge[tol].next=head[v];
    	head[v]=tol++;
    }
    int last;
    int dep[maxn],gap[maxn];
    void bfs(int sour,int sink)
    {
    	queue<int>	q;
    	int i,u,v;
    	memset(dep,-1,sizeof(dep));
    	memset(gap,0,sizeof(gap));
    	q.push(sink);dep[sink]=0;gap[0]=1;
    	while(!q.empty())
    	{
    		u=q.front();q.pop();
    		for(i=head[u];i!=-1;i=edge[i].next)
    		{
    			v=edge[i].v;
    			if(dep[v]==-1&&edge[i].cap==0)
    			{
    				dep[v]=dep[u]+1;
    				q.push(v);
    				gap[dep[v]]++;
    			}
    		}
    	}
    }
    int sap(int sour,int sink,int n)
    {
    	bfs(sour,sink);
    	int max_flow=0,top=0,i,u;
    	int S[maxn],cur[maxn];
    	for(i=0;i<=n;i++)
    		cur[i]=head[i];
    	u=sour;
    	while(dep[u]<last)
    	{
    		if(u==sink)
    		{
    			int temp=INF,inser;
    			for(i=0;i<top;i++)
    				if(edge[S[i]].cap<temp)
    				{
    					temp=edge[S[i]].cap;
    					inser=i;
    				}
    			for(i=0;i<top;i++)
    			{
    				edge[S[i]].cap-=temp;
    				edge[S[i]^1].cap+=temp;
    			}
    			max_flow+=temp;
    			top=inser;
    			u=edge[S[top]].u;
    		}
    		if(u!=sink&&gap[dep[u]-1]==0)	break;
    		for(i=cur[u];i!=-1;i=edge[i].next)
    			if(edge[i].cap>0&&dep[u]==dep[edge[i].v]+1)
    				break;
    		if(i!=-1)
    		{
    			cur[u]=i;
    			S[top++]=i;
    			u=edge[i].v;
    		}
    		else
    		{
    			int mi=last;
    			for(i=head[u];i!=-1;i=edge[i].next)
    				if(edge[i].cap>0&&dep[edge[i].v]<mi)
    				{
    					mi=dep[edge[i].v];
    					cur[u]=i;
    				}
    			gap[dep[u]]--;
    			dep[u]=mi+1;
    			gap[dep[u]]++;
    			if(u!=sour)	u=edge[S[--top]].u;
    		}
    	}
    	return max_flow;
    }
    void dfs(int u)
    {
    	int i,v;
    	vis[u]=true;
    	last++;
    	for(i=0;i<distree[u].size();i++)
    	{
    		v=distree[u][i];
    		addedge(u,v,1);
    		if(!vis[v])	dfs(v);
    	}
    }
    int dij(int sour,int sink)
    {
    	bool done[maxn];
    	priority_queue<shit>	q;
    	int i,u,v,w;
    	shit pp;
    	pp.v=sour;pp.w=0;
    	q.push(pp);
    	memset(dis,INF,sizeof(dis));
    	memset(done,false,sizeof(done));
    	dis[sour]=0;
    	while(!q.empty())
    	{
    		pp=q.top();q.pop();
    		u=pp.v;
    		if(done[u])	continue;//永久标号没有wa数发 
    		done[u]=true;
    		for(i=0;i<g[u].size();i++)
    		{
    			v=g[u][i].v;w=g[u][i].w;
    			if(dis[v]==dis[u]+w)
    				distree[v].push_back(u);
    			else if(dis[v]>dis[u]+w)
    			{
    				dis[v]=dis[u]+w;
    				pp.v=v;pp.w=dis[v];
    				q.push(pp);
    				distree[v].clear();
    				distree[v].push_back(u);
    			}
    		}	
    	}
    	return dis[sink];
    }
    int main()
    {
    	int i,j,t,u,v,w,n,m;
    	int sour,sink;
    	scanf("%d",&t);
    	while(t--)
    	{
    		scanf("%d%d",&n,&m);
    		shit pp;
    		init();
    		for(i=1;i<=n;i++)
    		{
    			g[i].clear();
    			distree[i].clear();
    		}
    		for(i=1;i<=m;i++)
    		{
    			scanf("%d%d%d",&u,&v,&w);
    			pp.v=v;pp.w=w;
    			g[u].push_back(pp);//曾建立无向边wa数发 
    		}
    		scanf("%d%d",&sour,&sink);
    		int bitch=dij(sour,sink);
    		if(bitch==INF)
    		{
    			printf("0
    ");
    			continue;
    		}
    		memset(vis,false,sizeof(vis));
    		last=0;
    		dfs(sink);
    		bitch=sap(sink,sour,n);
    		printf("%d
    ",bitch);
    	}
    	return 0;
    }
    
  • 相关阅读:
    注册表
    windows.location.href在IE6下停止工作
    LINUX配置IP的三种方式
    InnoSetup 打包代码 检测.netFramework
    SQLiteHelper
    黑马程序员_看视频记笔记_C#编程基础02
    通过注册表来检测是否安装Office
    SQLiteHelper
    TSQL
    IIS下发布关于Excel导入导出时遇到的问题集锦
  • 原文地址:https://www.cnblogs.com/bitch1319453/p/4776971.html
Copyright © 2011-2022 走看看