TJU 2840 Apple Tree

这题也是求重联通分量的,若将每个重联通分量都看成一个点的话,原问题的图就转化成一个树。然后就是要求该树中某些 子节点的权值和最大。


#include <stack>
#include 
<vector>

using namespace std;


struct road
{
    
int ID, next;
};

stack
<int> S;

vector 
<road> E[10000];
int ID[10000], Low[10000];
int P[10000];
int V[10000];
int cnt;
int ans;
int N, M;



int DFS(int x, int flag)
{
    S.push(x);

    Low[x] 
= ID[x] = cnt++;

    
int ret = V[x];

    
for (int i = 0; i < E[x].size(); i++)
    {
        
if (E[x][i].ID == flag) continue;
    
        
        
int next = E[x][i].next;
        P[next] 
= x;

        
if (ID[next] == -1)
            ret 
+=DFS(next, E[x][i].ID);
        

            
if (Low[next] < Low[x]) Low[x] = Low[next];
            
if (ID[next] < Low[x]) Low[x] = ID[next];
        
    }
    
    
if (Low[x] != 0 && Low[x] == ID[x] && ret > ans) ans = ret;

    
if (Low[x] == ID[x])
    {
        
while (S.top() != x)
            S.pop();
        S.pop();
    }
    
return ret;
}
int main()
{
    
while (scanf("%d%d"&N, &M) == 2 && N && M)
    {
        
for (int i = 0; i < N; i++)
            E[i].clear();

        
for (int i = 0; i < M; i++)
        {
            
int x, y;
            scanf(
"%d%d"&x, &y);
            x
--,y--;
            road temp;
            temp.next 
= y;
            temp.ID 
= i;
            
            E[x].push_back(temp);

            temp.next 
= x;
            E[y].push_back(temp);
        }
        

        
        
for (int i = 0; i < N; i++)
            scanf(
"%d"&V[i]);


        
while (!S.empty()) S.pop();

        cnt 
= 0;
        ans 
= -1000000000;
        memset(ID, 
-1sizeof(ID));

        DFS(
0-1);

        
if (ans <= -1000000000)
            printf(
"No apple\n");
        
else
            printf(
"%d\n", ans);


    }
    
return 0;

相关文章: