zoukankan      html  css  js  c++  java
  • [杂题]「FJOI2018」所罗门王的宝藏

    题目大意

    给出一个(n)*(m)的空矩阵,每次可以使任意一行/列(+1/-1),给出(k)个位置的最终结果,询问是否存在解.

    (1<=n,m,k<=1000)

    解题思路

    考虑把每一行/列看成点,限制看成边权,操作就是把与某个点相连的所有边(+1/-1),询问能否使边权都变为(0).

    我们显然只需要考虑环上的情况,随便设环上某个点的值为(x),其他点都可以表示成(ax+b)的形式,考虑最后的一条环边是否满足即可.

    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn=2005;
    int tot,lnk[maxn],nxt[2*maxn],son[2*maxn],w[2*maxn];
    int T,n,m,K,pd,a[maxn],b[maxn];
    bool vis[maxn];
    void add(int x,int y,int z){nxt[++tot]=lnk[x];lnk[x]=tot;son[tot]=y;w[tot]=z;}
    void DFS(int x){
    	vis[x]=1;
    	for (int j=lnk[x];j;j=nxt[j]){
    		if (!vis[son[j]]) a[son[j]]=-a[x],b[son[j]]=w[j]-b[x],DFS(son[j]);
    		else if (a[son[j]]+a[x]!=0||b[x]+b[son[j]]!=w[j]) pd=0;
    	}
    }
    int main(){
    	freopen("exam.in","r",stdin);
    	freopen("exam.out","w",stdout);
    	scanf("%d",&T);
    	while(T--){
    		scanf("%d%d%d",&n,&m,&K),tot=0;
    		memset(lnk,0,sizeof(lnk));
    		while(K--){
    			int x,y,z;scanf("%d%d%d",&x,&y,&z);
    			add(x,y+n,z);add(y+n,x,z);
    		}
    		memset(vis,0,sizeof(vis));pd=1;
    		for (int i=1;i<=n;i++) if (!vis[i]) a[i]=1,DFS(i);
    		if (pd) printf("Yes
    ");else printf("No
    ");
    	}
    	return 0;
    } 
    
  • 相关阅读:
    简单的股票分析系统
    gtest日志在工程项目中的应用
    doctest初次体验
    python写的读取json配置文件
    logbook日志系统
    python3 pyodbc简单使用
    numpy中dtype
    python获取代码行号
    Python操作SQLServer示例(转)
    log4j与log4j.properties的配置
  • 原文地址:https://www.cnblogs.com/CHNJZ/p/11240407.html
Copyright © 2011-2022 走看看