 /**//*
一个图
每条边上有两个值(gcd,lcm) 其值是该边两个顶点u,v上值的gcd和lcm
现给出一些边,问有没存在顶点的值满足边的限制
n <= 100 , m <= n(n-1)/2
1 <= gcd , lcm <= 10^6

由于gcd , lcm比较小
选取任意一个顶点,枚举它的值val,val要满足val % gcd == 0 , lcm % val == 0
for( val = gcd ; val <= lcm ; val += gcd)
if( lcm % val == 0)
检查
由lcm = a * b / gcd ,知道了a就推出b了
所以由选取的那个点出发,去推出其他点的值,若之前已经推出了,判断其是否矛盾
*/
#include<iostream>
#include<cstring>
#include<map>
#include<algorithm>
#include<stack>
#include<queue>
#include<cmath>
#include<string>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<set>
#include<list>

using namespace std;

 struct Edge {
int v , l , g;
 Edge(int v , int g , int l): v(v), g(g), l(l) {
}
};

vector<Edge> E[101];
int ans[101];
stack<int> s;

 int gcd(int a , int b) {
return b == 0 ? a : gcd(b , a % b);
}

 int lcm(int a ,int b) {
return a / gcd(a,b) * b;
}


 bool chk(int u) {
s.push(u);
 for(vector<Edge>::iterator it = E[u].begin() ; it != E[u].end() ; it++) {
int v = it->v , g = it->g , l = it->l;
 if(l % ans[u] != 0 || ans[u] % g != 0) {
return false;
}
 if(ans[v] != -1) {
 if(gcd(ans[u], ans[v]) != g || lcm(ans[u], ans[v]) != l) {
return false;
}
 }else {
ans[v] = l / ans[u] * g ;
 if(!chk(v)) {
return false;
}
}
}
return true;
}

 bool gao(int u) {
 if(E[u].empty()) {
ans[u] = 1;
return true;
}
 while(!s.empty()) {//don't forget !!!
s.pop();
}
Edge e = E[u][0];
int g = e.g , l = e.l;
 for(int val = g ; val <= l ; val += g) {
 if(l % val !=0) {
continue;
}
ans[u] = val;
 if(chk(u)) {
return true;
 }else {
 while(!s.empty()) {
ans[s.top()] = -1;
s.pop();
}
}
}
return false;
}

int main()
  {
 for(int n, m; ~scanf("%d%d",&n, &m); ) {
 for(int i = 1 ; i <= n ; i ++) {
E[i].clear();
}
bool err = false;
 for(int i = 0 ; i < m ; i ++) {
int u, v, g, l;
scanf("%d%d%d%d",&u,&v,&g,&l);
E[u].push_back(Edge(v, g, l));
E[v].push_back(Edge(u, g, l));
 if(l % g != 0) {
err = true;
}
}

 if(!err) {
fill(ans+1,ans+1+n,-1);
 for(int u = 1 ; u <= n; u++) {
 if(ans[u] == -1) {
 if(!gao(u)) {
err = true;
break;
}
}
}
}

 if(err) {
puts("NO");
 }else {
puts("YES");
 for(int i = 1 ; i <= n ; i++) {
 if(i>1) {
putchar(' ');
}
printf("%d",ans[i]);
}
puts("");
}
}
return 0;
}
|
|
常用链接
随笔分类
Links
搜索
最新评论

|
|