# UNDF: UNDF-2026-000000485
# opencv-0001: tvUpdateConfictMap — O(C²×G) std::find on graphConflictMap vectors inside recursive DFS

## Location
`modules/dnn/src/op_timvx.cpp` lines 27–41, line 869–875
Repository: https://github.com/opencv/opencv

## Severity
**HIGH** — Called during DNN network initialization when partitioning layers across TimVX sub-graphs. A DNN with C consumer edges and G TimVX graphs incurs O(C²×G) work per call site due to recursive DFS with linear conflict-set membership at every node. For transformer architectures with many attention layers (hundreds of consumer connections), this is a serious bottleneck.

## Complexity
- Before: O(C × G) per recursive call, O(C²×G) over full DFS traversal
- After: O(C + G) over full DFS traversal using unordered_set

## Defective Code

```cpp
// op_timvx.cpp:23-41
void Net::Impl::tvUpdateConfictMap(int graphIndex, LayerData& ld,
                                   std::vector<std::vector<int>>& graphConflictMap)
{
    if (ld.consumers.empty()) return;
    for (int i = 0; i < ld.consumers.size(); i++)
    {
        LayerData &consumerld = layers[ld.consumers[i].lid];
        std::vector<int>::iterator it = std::find(
            graphConflictMap[ld.consumers[i].lid].begin(),  // O(G) linear scan
            graphConflictMap[ld.consumers[i].lid].end(),
            graphIndex);

        if (it == graphConflictMap[ld.consumers[i].lid].end())
        {
            graphConflictMap[ld.consumers[i].lid].push_back(graphIndex);
            tvUpdateConfictMap(graphIndex, consumerld, graphConflictMap);  // recursive
        }
    }
}

// op_timvx.cpp:864-875
bool TimVXInfo::isConflict(int layerId, int graphIndex)
{
    if (graphConflictMap[layerId].empty()) return false;
    std::vector<int>::iterator it = std::find(  // O(G) linear scan
        graphConflictMap[layerId].begin(),
        graphConflictMap[layerId].end(), graphIndex);
    return it != graphConflictMap[layerId].end();
}
```

**Problem:** `graphConflictMap` stores each layer's conflicting graph indices as a `vector<int>`.
Every `std::find` call is O(G) where G = number of TimVX sub-graphs. The recursive DFS
visits every consumer of every layer making the total O(C × G). Since this is recursive
over the consumer graph (depth up to C nodes), total work is O(C²×G).

## Fixed Code

```cpp
// Change graphConflictMap type from vector<vector<int>> to vector<unordered_set<int>>

void Net::Impl::tvUpdateConfictMap(int graphIndex, LayerData& ld,
                                   std::vector<std::unordered_set<int>>& graphConflictMap)
{
    if (ld.consumers.empty()) return;
    for (int i = 0; i < ld.consumers.size(); i++)
    {
        int cid = ld.consumers[i].lid;
        LayerData &consumerld = layers[cid];
        if (graphConflictMap[cid].insert(graphIndex).second)  // O(1) insert+dedup
        {
            tvUpdateConfictMap(graphIndex, consumerld, graphConflictMap);
        }
    }
}

bool TimVXInfo::isConflict(int layerId, int graphIndex)
{
    return graphConflictMap[layerId].count(graphIndex) > 0;  // O(1)
}
```

## CWE
CWE-407: Inefficient Algorithmic Complexity — O(C²×G) → O(C+G)
