zoukankan      html  css  js  c++  java
  • 【BZOJ5470】[FJOI2018]所罗门王的宝藏()

    【BZOJ5470】[FJOI2018]所罗门王的宝藏()

    题面

    BZOJ
    洛谷

    (n+m)个变量,给定(k)组限制,每次告诉你(a_i+b_j=c_k),问是否有可行解。

    题解

    一道很呆的题目,我都不知道应该算什么类型了。。。
    把行列拆开,对于一个限制(x,y,c),连边(x)行到(y)列,边权为(c)
    然后(dfs)一遍,如果存在环的话显然必须要环上存在合法解,那么随便令一个东西为(x),记录每个值为(ax+b)的形式,检查二分图是否合法。

    #include<iostream>
    #include<cstdio>
    using namespace std;
    #define MAX 2020
    inline int read()
    {
    	int x=0;bool t=false;char ch=getchar();
    	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    	if(ch=='-')t=true,ch=getchar();
    	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    	return t?-x:x;
    }
    int n,m,K;
    int a[MAX],b[MAX];bool vis[MAX];
    struct Line{int v,next,w;}e[MAX];
    int h[MAX],cnt=1;
    inline void Add(int u,int v,int w){e[cnt]=(Line){v,h[u],w};h[u]=cnt++;}
    bool Flag;
    void dfs(int u)
    {
    	vis[u]=true;if(!Flag)return;
    	for(int i=h[u];i;i=e[i].next)
    	{
    		int v=e[i].v,w=e[i].w;
    		if(!vis[v])a[v]=-a[u],b[v]=w-b[u],dfs(v);
    		else if(a[v]+a[u]!=0||b[u]+b[v]!=w){Flag=false;return;}
    	}
    }
    int main()
    {
    	int T=read();
    	while(T--)
    	{
    		n=read();m=read();K=read();cnt=1;
    		for(int i=1;i<=K;++i)
    		{
    			int x=read(),y=read(),d=read();
    			Add(x,y+n,d);Add(y+n,x,d);
    		}
    		Flag=true;
    		for(int i=1;Flag&&i<=n;++i)
    			if(!vis[i])a[i]=1,b[i]=0,dfs(i);
    		puts(Flag?"Yes":"No");
    		for(int i=1;i<=n+m;++i)vis[i]=false,h[i]=0;
    	}
    	return 0;
    }
    
  • 相关阅读:
    URAL 1018 Binary Apple Tree
    URAL 1029 Ministry
    URAL 1039 Anniversary Party
    URAL 1078 Segments
    Codeforces 918D
    Codeforces 918C
    URAL 1495 One-two, One-two 2
    URAL 1244 Gentlemen
    URAL 1658 Sum of Digits
    URAL 1081 Binary Lexicographic Sequence
  • 原文地址:https://www.cnblogs.com/cjyyb/p/10447085.html
Copyright © 2011-2022 走看看