Check if the system of equations have a solution - c++

Question:
There are N variables x1, x2, x3, ...... xN.
There are M triplets such that triple {i,j,c} indicate that xi = xj + c and so each triplet denote an equation. Check if the system of equations have atleast one solution.
My idea:
I considered the system of equations as a graph of N nodes labelled from 1 to N. If {i,j,c} is a triplet then, i->j is an edge with weight c and j->i is an edge with weight -c. With 0 as the source, I applied Bellman Ford algorithm to detect any negative cycles. If there is any positive sum cycle, then there must also be a negative sum cycle, which can be traced with Bellman Ford.
Following is the code
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
#define INF (1<<30)
int main(){
int T;
cin>>T;
while(T--){
int N;int M;
cin>>N;cin>>M;
vector<vector<int>> edges;
for (int i=0;i<M;++i){
int first;int second;int third;
cin>>first;cin>>second;cin>>third;
first--;second--;
edges.push_back({first,second,third});
edges.push_back({second,first,-third});
}
vector<int> distances(N,INF);
distances[0] = 0;
for (int i=1;i<=N;++i){
for (int j=0;j<edges.size();++j){
int from = edges[j][0];
int to = edges[j][1];
int weight = edges[j][2];
if (distances[from]+weight<distances[to]){
distances[to] = distances[from] + weight;
}
}
}
int flag = 0;
for (int j=0;j<edges.size();++j){
int from = edges[j][0];
int to = edges[j][1];
int weight = edges[j][2];
if (distances[from]+weight<distances[to]){
flag = 1;
break;
}
}
if (flag==1){
cout << "NO" << endl;
}
else{
cout << "YES" << endl;
}
}
}
Is the idea correct? I am unable to generate test cases against the above logic. But, the code failed to give correct output for many test cases.
Can somebody point out the mistake.
Thank you

Related

Procedure that generate the polynomial coefficients and a function to calculate the value of it

So essentially, I'm trying to code a small block that should create or generate coefficients for polynomial n-degree that can be represented through vector which is a=[a0, a1..an] given the basic formula is
Well, the issue is when doing a function to get value of polynomial P from point "x" it returns value from entirely using Horner's Rule which it's not the same result as intended although not sure which one I should put on. The math basic explanation tells me at least something out of:
E.g: n=2; (A[i] stack terms by 4, 2, 1) and calculates P(value of x) = 4 * x ^ 0 – 2 * x ^ 1 + 1 * x ^ 2 = 4 – 2x + x2 = x2 – 2x + 4 = 4
With other words , can't find the culprit when for "x" value is meant to go through "i" variable numbered wrong by exponent and the result gets output for P(0)=7 while it shouldn't be and concrete as in P(0) = 0 ^ 2 – 2 * 0 + 4 = 4
Here's a little snippet went through so far, I would appreciate if someone could point me in the right direction.
double horner(const double&x, const int& n, const double& nn) {
if (n < 0)
return nn;
else {
double m; cin>>m;
return horner(x, n-1, nn*x+m);
}
}
int main() {
int n;double x;
cout << "n=";cin >> n;
cout << "x=";cin >> x;
cout << "P(0)=" << horner(x, n, 0);
return 0;
}
Edit: My brain farted for a moment somewhere while was coding and continuously revising the case, I forgot to mention what exactly are the parts of each variables for the program to avoid confusion yes, so:
n, polynomial grade;
p, polynomial coefficient;
x, the point in which evaluates;
And here given the grade equation to polynomial
which any negative and positive input terms adding by exponent to these coefficients are the steps that holds the result exception, hence the reason Horner's rule that it reduces the number of multiplication operations.
Edit: After few hours, managed to fix with polynomial evaluating issue, the only question remains how I'd suppose to generate coefficients using method std::vector ?
float honer(float p[], int n, float x)
{
int i;
float val;
val = p[n];
for (i = n - 1; i >= 0; i--)
val = val * x + p[i];
return val;
}
int main()
{
float p[20]; // Coefficient of the initial polynomial
int n; // Polynomial degree -n
float x; // Value that evaluates P -> X
cout << "(n) = ";
cin >> n;
for (int i = n; i >= 0; i--)
{
cout << "A[" << i << "]=";
cin >> p[i];
}
cout << "x:= ";
cin >> x;
cout << "P(" << x << ")=" << honer(p, n, x);
//Result (input):
//n: 2,
//P[i]: 4, -2, 1 -> x: 0, 1
// Result (output):
//P() = 4
}
Expect some certain output scenarios given below input if assigned:

hostel visit question (priority queue application )

question: Dean of MAIT is going to visit Hostels of MAIT. As you know that he is a very busy person so he decided to visit only the first "K" nearest Hostels. Hostels are situated on a 2D plane. You are given the coordinates of hostels and you have to answer the Rocket distance of Kth nearest hostel from the origin ( Dean's place )
Input Format
The first line of input contains Q Total no. of queries and K There are two types of queries:
first type: 1 x y For query of 1st type, you came to know about the coordinates ( x, y ) of the newly constructed hostel. second type: 2 For query of 2nd type, you have to output the Rocket distance of Kth nearest hostel till now.
//The Dean will always stay at his place ( origin ). It is guaranteed that there will be at least k queries of type 1 before the first query of type 2.
Rocket distance between two points ( x2 , y2 ) and ( x1 , y1 ) is defined as (x2 - x1)2 + (y2 - y1)2
Constraints
1 < = k < = Q < = 10^5 -10^6 < = x , y < = 10^6
Output Format
For each query of type 2 output the Rocket distance of Kth nearest hostel from Origin.//
This is my code:
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
class roomno
{
public:
int x;
int y;
roomno(int x,int y)
{
this->x=x;
this->y=y;
}
void print()
{
cout<<"location"<<"("<<x<<","<<y<<")"<<endl;
}
int distance ()
{
return (x*x+y*y);
}
};
class roomcompare
{
public:
bool operator() (roomno r1,roomno r2)
{
return r1.distance()>r2.distance();
}
};
int main()
{
int x[1000]},y[1000];
int l,k=0;
priority_queue<roomno,vector<roomno>,roomcompare> pq;
int n,i,j;
cin>>n>>l;
//cin>>n;
cin.ignore();
for( i=0;i<n;i++)
{
cin>>x[i];
}
cin.ignore();
for( j=0;j<n;j++)
{
cin>>y[j];
}
cin.ignore();
for(i=0;i<n;i++ )
{
roomno r1(x[i],y[i]);
pq.push(r1);
}
while(!pq.empty()&&k!=l)
{ k++;
roomno r2=pq.top();
r2.print();
pq.pop();
}
return 0;
}
Original link to code: https://codeshare.io/2j1bkA
What's wrong with my code?
Please consider adding what problem you are facing in your post. I've seen your code but I couldn't help with your code as I even saw a syntax error in your code and didn't know if it was the problem.
If I didn't misunderstand your question, std::set will fit better than priority queue as it is not possible to remove the largest item in a priority queue(min heap). The following code should work:
#include <iostream>
#include <set>
using namespace std;
using ll = long long;
multiset<ll> distances;
int main() {
ll n, k;
cin >> n >> k;
for(ll i = 0; i < n; ++i) {
ll query;
cin >> query;
if (query == 1) {
ll x, y;
cin >> x >> y;
distances.insert(x * x + y * y);
if (distances.size() > k) {
distances.erase(--distances.end());
}
} else {
cout << *distances.rbegin() << '\n';
}
}
return 0;
}

Solving Wormholes (ZCO 2012)

Description:
The year is 2102 and today is the day of ZCO. This year there are N contests and the starting and ending times of each contest is known to you. You have to participate in exactly one of these contests. Different contests may overlap. The duration of different contests might be different.
There is only one examination centre. There is a wormhole V that transports you from your house to the examination centre and another wormhole W that transports you from the examination centre back to your house. Obviously, transportation through a wormhole does not take any time; it is instantaneous. But the wormholes can be used at only certain fixed times, and these are known to you.
So, you use a V wormhole to reach the exam centre, possibly wait for some time before the next contest begins, take part in the contest, possibly wait for some more time and then use a W wormhole to return back home. If you leave through a V wormhole at time t1 and come back through a W wormhole at time t2, then the total time you have spent is (t2 - t1 + 1). Your aim is to spend as little time as possible overall while ensuring that you take part in one of the contests.
You can reach the centre exactly at the starting time of the contest, if possible. And you can leave the examination centre the very second the contest ends, if possible. You can assume that you will always be able to attend at least one contest–that is, there will always be a contest such that there is a V wormhole before it and a W wormhole after it.
For instance, suppose there are 3 contests with (start,end) times (15,21), (5,10), and (7,25), respectively. Suppose the V wormhole is available at times 4, 14, 25, 2 and the W wormhole is available at times 13 and 21. In this case, you can leave by the V wormhole at time 14, take part in the contest from time 15 to 21, and then use the W wormhole at time 21 to get back home. Therefore the time you have spent is (21 - 14 + 1) = 8. You can check that you cannot do better than this.
Input:
The first line contains 3 space separated integers N, X, and Y, where N is the number of contests, X is the number of time instances when wormhole V can be used and Y is the number of time instances when wormhole W can be used. The next N lines describe each contest. Each of these N lines contains two space separated integers S and E, where S is the starting time of the particular contest and E is the ending time of that contest, with S < E. The next line contains X space separated integers which are the time instances when the wormhole V can be used. The next line contains Y space separated integers which are the time instances when the wormhole W can be used.
Output:
Print a single line that contains a single integer, the minimum time needed to be spent to take part in a contest.
My code:
#include <iostream>
#include <algorithm>
#include <vector>
#include <bits/stdc++.h>
#define loop(i,n) for(int i=0;i<n;++i)
#define FOR(i,a,b) for (int i = a; i < b; ++i)
#define ll long long
#define inf 9223372036854775807
#define printgrid(arr,m,n){cout<<"[";for(int i=0;i<m;++i){if(i!=0)cout<<" ";cout<<"[";for(int j=0;j<n;++j){cout<<arr[i][j];if(j!=n-1)cout<<" ";}cout<<"]";if(i!=m-1)cout<<endl;}cout<<"]"<<endl;}
using namespace std;
int searchl(int *arr,int s,int v)
{
int l=0;
int r=s-1;
while(l<=r)
{
int m = (l+r)/2;
if (arr[m] == v) return v;
if(arr[m]<v)
{
l = m + 1;
} else {
r = m - 1;
}
}
if (r<0) r=0;
return arr[r];
}
int searchh(int *arr,int s,int v)
{
int l=0;
int r=s-1;
while(l<=r)
{
int m = (l+r)/2;
if (arr[m] == v) return v;
if(arr[m]<v)
{
l = m + 1;
} else {
r = m - 1;
}
}
if(l>s-1) l=s-1;
return arr[l];
}
int main() {
int n,x,y;
cin>>n>>x>>y;
vector<pair<int,int>> v(n);
int a[x];
int b[y];
loop(i,n) cin >> v[i].first >> v[i].second;
loop(i,x) cin >> a[i];
loop(i,y) cin >> b[i];
sort(a,a+x);
sort(b,b+y);
int mn = 0x7fffffff;
int l;
int u;
loop(i,n)
{
l = searchl(a,x,v[i].first);
u = searchh(b,y,v[i].second);
mn = min(mn,(u-l+1));
}
cout << mn << endl;
}
What I tried is I use binary search for the lower range and upper range. and return the closest integer in the list. This should result in the lowest difference. This code AC's in 90% of the testcases however fails two testcases with a wrong answer.
Correct code:
#include <iostream>
#include <algorithm>
#include <vector>
#include <bits/stdc++.h>
#define loop(i,n) for(int i=0;i<n;++i)
#define FOR(i,a,b) for (int i = a; i < b; ++i)
#define ll long long
#define inf 9223372036854775807
#define printgrid(arr,m,n){cout<<"[";for(int i=0;i<m;++i){if(i!=0)cout<<" ";cout<<"[";for(int j=0;j<n;++j){cout<<arr[i][j];if(j!=n-1)cout<<" ";}cout<<"]";if(i!=m-1)cout<<endl;}cout<<"]"<<endl;}
using namespace std;
int searchl(int *arr,int s,int v)
{
int l=0;
int r=s-1;
while(l<=r)
{
int m = (l+r)/2;
if (arr[m] == v) return v;
if(arr[m]<v)
{
l = m + 1;
} else {
r = m - 1;
}
}
if (r<0) return -1;
return arr[r];
}
int searchh(int *arr,int s,int v)
{
int l=0;
int r=s-1;
while(l<=r)
{
int m = (l+r)/2;
if (arr[m] == v) return v;
if(arr[m]<v)
{
l = m + 1;
} else {
r = m - 1;
}
}
if(l>s-1) return -1;
return arr[l];
}
int main() {
cin.sync_with_stdio(false);
cin.tie(NULL);
int n,x,y;
cin>>n>>x>>y;
vector<pair<int,int>> v(n);
int a[x];
int b[y];
loop(i,n) cin >> v[i].first >> v[i].second;
loop(i,x) cin >> a[i];
loop(i,y) cin >> b[i];
sort(a,a+x);
sort(b,b+y);
int mn = 0x7fffffff;
int l;
int u;
loop(i,n)
{
l = searchl(a,x,v[i].first);
u = searchh(b,y,v[i].second);
if(u==-1 or l==-1) continue;
mn = min(mn,(u-l+1));
}
cout << mn << endl;
}

Isolating some vertices in a weighted tree with minimum cost

Suppose we are given a weighted tree and some set of vertices of that tree. The problem is to isolate those vertices(e.g. there should not be paths between them) by removing edges from the tree, such that the sum of the weights of removed edges is minimal.
I have been trying to solve this problem for about two hours, then I found solution in C++, but there was no explanation. As I understood it uses Dynamic Programming technique.
My question is what is the basic idea of solving this problem?
Thanks!
Here is the solution.
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
#define PB push_back
#define MP make_pair
typedef long long LL;
const int MAXN = 100005;
const LL inf = 1LL << 55;
int N, K;
bool bad[MAXN];
LL dp[MAXN][2];
vector<pair<int, int> > adj[MAXN];
void dfs(int u, int fa) {
dp[u][1] = 0;
dp[u][0] = bad[u] ? inf : 0;
for (int i = 0; i < adj[u].size(); i++) {
int v = adj[u][i].first, w = adj[u][i].second;
if (v != fa) {
dfs(v, u);
dp[u][1] += min(dp[v][0], dp[v][1] + w);
dp[u][1] = min(dp[u][1], dp[u][0] + dp[v][1]);
if (!bad[u])
dp[u][0] += min(dp[v][0], dp[v][1] + w);
}
}
}
int main() {
cin >> N >> K;
for (int i = 1; i < N; i++) {
int a, b, c;
cin >> a >> b >> c;
adj[a].PB(MP(b, c)); adj[b].PB(MP(a, c));
}
memset(bad, false, sizeof(bad));
for (int i = 0; i < K; i++) {
int x;
cin >> x;
bad[x] = true;
}
dfs(0, -1);
LL ret = min(dp[0][0], dp[0][1]);
cout << ret << endl;
return 0;
}
Formally, the problem is, given an acyclic undirected graph with weighted edges, together with a set of terminal vertices, find the minimum set of edges whose removal means that, for all pairs of distinct terminals, those terminals are no longer connected.
Root the graph arbitrarily and treat it as a general tree. We run a dynamic program that operates bottom-up on the vertices. Each vertex u has two labels: dp[u][0] is the minimum weight of edges to be removed in the subtree rooted at u so that no terminal in the subtree is connected to another terminal or to u, and dp[u][1] is the minimum removal weight that leaves exactly one subtree terminal connected to u. We have a recurrence
{ infinity if v is a terminal
dp[u][0] = { sum dp[v][0] otherwise
{ children v of u
dp[u][1] = min dp[v][1] + sum min(dp[w][0], dp[w][1] + weight(uw)),
children v of u other children w of v
taking an empty min to be infinity.

C++ Detecting Squares

I built the following code to read 4 pairs of coordinates to calculate if it's a square or not:
#include <iostream>
using namespace std;
struct {
int x;
int y;
}a[10];
int dist(int x1, int y1, int x2, int y2)
{
// function to compute the (square of the) distance between two points
int c1, c2;
c1 = x2-x1;
c2 = y2-y1;
return (c1*c1)+(c2*c2);
}
int main()
{
int d1, d2, d3, d4;
for (int i=1; i<=4; i++)
{
cout << 'X' << i << '='; cin >> a[i].x;
cout << 'Y' << i << '='; cin >> a[i].y;
}
d1 = dist(a[1].x, a[1].y, a[2].x, a[2].y);
d2 = dist(a[2].x, a[2].y, a[3].x, a[3].y);
d3 = dist(a[3].x, a[3].y, a[4].x, a[4].y);
d4 = dist(a[4].x, a[4].y, a[1].x, a[1].y);
if(d1==d2 && d1==d3 && d1==d4)
cout << "Is a square";
else
cout << "Is not a square";
return 0;
}
The code works well enough, but I want to read multiple coordinates (more than four) and check every possible combination of four points to see if they make a square.
I can't figure out how to extend the method above to work with more than four points as input (and selecting all combination of four from that); can anyone give me a hint/hand please?
This sounds like a complete-graph problem. Since all points are int's, one thing I can think of is doing a depth-first search, without duplicates, with the distance^2 as the weight. And you sorta need a dual-pseudograph to keep the angle info (a boolean suffices for right-angle v.s. non-right-angle).
Start from a point 0 , step to the nearest neighbor 1, and then, start from the neighbor 1, find its neighbors 2,3,4 ..., and filter on two criteria: distance and angle. Each depth-first search needs only 4 steps max, since there are only 4 sides.
Iterate through all points, and book-keeping visited points, you may track how many squares made during the way.
Here is some code that checks all combinations of four points to see if they are square. Note that your original method for testing "square" was faulty - first, even if points were given in the correct order, a diamond shape would (wrongly) be called "square"; second, if points were given in the "wrong" order, a square might not look square.
I fixed both those issues. Also, I created a simple nested loop that generates all possible combinations of four points and tests them; this can be made much more efficient (for example, if points 1,2 and 3 do not form a "isosceles right triangle" there is no point to test the fourth point - so you can save a lot of time by not testing for all other possible points). I will leave that for another time.
I did not bother writing the "input N points" part of the code - I don't think that is what you were struggling with. Let me know if I was wrong to assume that.
#include <iostream>
typedef struct{
int x;
int y;
} point;
int isSquare (point *p1, point *p2, point *p3, point *p4) {
double dx, dy;
double dd[6];
point *pp[4];
pp[0]=p1; pp[1]=p2; pp[2]=p3; pp[3]=p4;
int ii, jj, kk, nn;
kk = 0;
// loop over all combinations of first and second point
// six in all
for(ii=0; ii<3; ii++) {
for(jj=ii+1; jj<4; jj++) {
dx = pp[ii]->x - pp[jj]->x;
dy = pp[ii]->y - pp[jj]->y;
dd[kk]= dx*dx + dy*dy;
if (dd[kk]==0) return 0; // two identical points: not a square
if(kk>1) {
for(nn= 0; nn < kk-1; nn++) {
// if both are "sides", we expect their length to be the same;
// if one is a diagonal and the other a side, their ratio is 2
// since we are working with the square of the number
if (!(((2*dd[nn] == dd[kk] ) || (dd[nn] == dd[kk]) || 2*dd[kk] == dd[nn] ))) return 0;
}
}
kk++;
}
}
return 1; // got here: all combinations tested OK, we have a square
}
int main(void) {
// pick ten numbers - chosen so there are two squares
point p[10]={{1,2},{3,2},{1,4},{7,8},{2,4},{3,4},{6,7},{8,7},{2,5},{3,5}};
double d2[10][10];
int ii, jj, kk, ll;
// loop over all possible combinations:
// since there are just four to pick we can hard-wire the loop
for(ii=0; ii<7; ii++) {
for(jj = ii+1; jj<8; jj++) {
for(kk = jj+1; kk<9; kk++) {
for(ll = kk+1; ll<10; ll++) {
if(isSquare(p+ii, p+jj, p+kk, p+ll)) {
std::cout << "combination: " << ii << "," << jj << "," << kk << "," << ll << " is a square\n";
}
}
}
}
}
}
Output:
combination: 0,1,2,5 is a square
combination: 4,5,8,9 is a square