Well, it's real guesswork as to what is causing wrong answers (though I could see a few opportunities for timeout).
Are you able to post a link to the original task (not your rephrasing of it) so that we can see whether there are any constraints that we might have missed?
Here's one slightly complex try that anticipates a few unlikely possibilities in the input data.
#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <string>
usingnamespace std;
//======================================================================
struct Cell
{
longlong value = 0;
multiset<int> parents; // Perhaps a parent cell can be repeated?
bool refError = false;
};
//======================================================================
vector<Cell> readFormulae()
{
string dummy;
int N, M;
cin >> N >> M; getline( cin, dummy );
vector<Cell> result( 1 + N );
for ( int f = 0; f < M; f++ )
{
string line;
getline( cin, line );
stringstream ss( line );
int i;
ss >> dummy >> i;
ss >> result[i].value;
for ( int x; ss >> x; )
{
// Perhaps input has non-existent cells?
if ( result[i].value < 1 || result[i].value > N ) result[i].refError = true;
result[i].parents.insert( result[i].value );
result[i].value = x;
}
}
return result;
}
//======================================================================
bool getValue( int n, vector<Cell> &cells, const set<int> &sequence )
{
for ( int p : cells[n].parents )
{
// Direct dependency on reference error
if ( cells[p].refError )
{
cells[n].refError = true;
returnfalse;
}
set<int> extended = sequence;
// Check for a cycle (all cells in it would fail if so)
if ( !extended.insert( p ).second )
{
for ( int e : extended ) cells[e].refError = true;
returnfalse;
}
// Otherwise recurse onward
if ( !getValue( p, cells, extended ) )
{
cells[n].refError = true;
returnfalse;
}
cells[n].value += cells[p].value;
}
// Already updated the cell value, so prevent any further adding
cells[n].parents.clear();
returntrue;
}
//======================================================================
int main()
{
vector<Cell> cells = readFormulae();
for ( int n = 1; n < cells.size(); n++ )
{
set<int> sequence{ n };
getValue( n, cells, sequence );
if ( cells[n].refError ) cout << "#REF!" << '\n';
else cout << cells[n].value << '\n';
}
}
//======================================================================
Hi lastchance, I'd like to ask about !extended.insert( p ).second at line61, who is insert( p ).second, is it the second value of cells[n].parents, why can it check if there's a cycle?thank you.
Although we don't often use the return value, std::set.insert() returns a pair consisting of:
an iterator to the inserted value (if successful); a boolean for whether the insert was successful or not.
The insert will fail (and hence the second element of the pair will be false) if the item that you try to insert in the set is already there - which is the standard test for a cycle: you've seen it before.
If you have a cycle then you have the Catch-22 situation: you can't insert the value at a node ... without knowing the value at that node.