• GDOI2018 day2 巡逻


    和标算不同的做法。
    先建立最短路树。
    引理:最多只会经过一条非树边。
    画图会发现是正确的
    建立源点开始的最短路树,把源点的每一个子树染色。
    枚举每条边,如果两端点颜色不同,则统计答案。
    时间复杂度(O(n^3))

    #include<bits/stdc++.h>
    using namespace std;
    #define N 410
    int n,q,a[N][N],d[N],f[N],cl[N],h[N],v[N*2],nxt[N*2],dd[N],ec,w[N*2],vi[N],vv[N];
    void add(int x,int y,int z){
    	v[++ec]=y;
    	w[ec]=z;
    	nxt[ec]=h[x];
    	h[x]=ec;
    }
    void dfs(int x,int fa,int c){
    	cl[x]=c;
    	for(int i=h[x];i;i=nxt[i])
    		if(v[i]!=fa){
    			dd[v[i]]=dd[x]+w[i];
    			dfs(v[i],x,c);
    		}
    }
    void dj(int s){
    	memset(v,0,sizeof(v));
    	memset(nxt,0,sizeof(nxt));
    	memset(h,0,sizeof(h));
    	memset(cl,0,sizeof(cl));
    	ec=0;
    	for(int i=0;i<=n;i++){
    		d[i]=1e7;
    		vv[i]=f[i]=dd[i]=cl[i]=0;
    	}
    	d[s]=0;
    	for(int i=1;i<=n;i++){
    		int t=0;
    		for(int j=1;j<=n;j++)
    			if(d[t]>d[j]&&!vv[j]&&vi[j])
    				t=j;
    		vv[t]=1;
    		if(!t)
    			break;
    		for(int j=1;j<=n;j++)
    			if(j!=t&&d[j]>d[t]+a[t][j]&&!vv[j]&&vi[j]){
    				f[j]=t;
    				d[j]=d[t]+a[t][j];
    			}
    	}
    	for(int i=1;i<=n;i++)
    		if(i!=s&&vi[i]&&vi[f[i]])
    			add(f[i],i,a[f[i]][i]);
    	int c=0;
    	for(int i=1;i<=n;i++)
    		if(i!=s&&vi[i]&&!cl[i]){
    			dd[i]=a[s][i];
    			dfs(i,s,++c);
    		}
    }
    int main(){
    	freopen("patrol.in","r",stdin);
    	freopen("patrol.out","w",stdout);
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=n;j++){
    			scanf("%d",&a[i][j]);
    			if(a[i][j]==-1)
    				a[i][j]=1e7;
    		}
    		vi[i]=1;
    	}
    	scanf("%d",&q);
    	while(q--){
    		int op,x;
    		scanf("%d%d",&op,&x);
    		if(op)
    			vi[x]^=1;
    		else{
    			dj(x);
    			int ans=1e8;
    			for(int i=1;i<=n;i++)
    				for(int j=1;j<=n;j++)
    					if(vi[i]&&vi[j]&&cl[i]!=cl[j]&&f[j]!=i&&f[i]!=j)
    						ans=min(ans,a[i][j]+dd[i]+dd[j]);
    			if(ans>=1e7)
    				puts("-1");
    			else
    				printf("%d
    ",ans);
    		}
    	}
    }
    
  • 相关阅读:
    sql server 查看锁表SQL【转】
    Delphi 使用TAdoQuery执行存储过程的样例
    Delphi调用MSSQL存储过程返回的多个数据集的方法
    cxGrid类似pagecontrol的效果
    sqlserver trigger(触发器)-更新某几列数据时触发【转】
    FormatFloat 格式化浮点数
    TADOConnection.Close
    cxVerticalGrid
    Delphi中比较两个对象是否一致及地址是否相同[转]
    Linux学习-分析登录档
  • 原文地址:https://www.cnblogs.com/ctmlpfs/p/14503544.html
Copyright © 2020-2023  润新知