Pat 1003 Emergency (25)



//无向图上求最短路径的个数,及最短路径上点权值和的最大值
//没有用最短路算法,直接深搜
//第一遍深搜求最短路,第二遍深搜计算最短路径的个数和最短路径上点权值和的最大值
//
//
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
const int maxn=505;
const int  inf=0xfffffff;
int _gh[maxn][maxn];
int _city1,_city2,_cnt;
int _n,_m,_max,_team;
int  _numOfTeam[maxn];
bool _used[maxn];

void dfs_1(int _x,int _distance) {
    int _i;
    if(_distance>_max)
        return ;
    if( _x==_city2) {
        if(_distance<_max)
            _max=_distance;
    }
    for(_i=0; _i<_n; _i++) {
        if(_gh[_x][_i]>=0&&!_used[_i]) {
            _distance+=_gh[_x][_i];
            _used[_i]=true;
            dfs_1(_i,_distance);
            _distance-=_gh[_x][_i];
            _used[_i]=false;
        }
    }
}

void dfs_2(int _x,int _distance,int _ans) {
    int _i;
    if(_distance>_max)
        return ;
    if( _x==_city2&&_distance==_max) {
        if(_ans>_team)
            _team=_ans;
        _cnt++;
    }
    for(_i=0; _i<_n; _i++) {
        if(_gh[_x][_i]>=0&&!_used[_i]) {
            _distance+=_gh[_x][_i];
            _ans+=_numOfTeam[_i];
            _used[_i]=true;
            dfs_2(_i,_distance,_ans);
            _used[_i]=false;
            _distance-=_gh[_x][_i];
            _ans-=_numOfTeam[_i];
        }
    }
}

int main() {
    int i,j,k;
    while(cin>>_n>>_m>>_city1>>_city2) {

        memset(_gh,-1,sizeof(_gh));
         memset(_used,false,sizeof(_used));
        _cnt=0;
        _team=0;
        for(i=0; i<_n; i++)
            scanf("%d",&_numOfTeam[i]);
        int _a,_b,_c;
        while(_m--) {
            scanf("%d %d %d",&_a,&_b,&_c);
            if(_gh[_a][_b]>_c||_gh[_a][_b]==-1) {
                _gh[_a][_b]=_c;
                _gh[_b][_a]=_c;
            }
        }
        if(_city1==_city2) {
            printf("1 %d\n",_numOfTeam[_city1]);
            continue;
        }
        _max=inf;
        dfs_1(_city1,0);
        memset(_used,false,sizeof(_used));
        dfs_2(_city1,0,_numOfTeam[_city1]);
        printf("%d %d\n",_cnt,_team);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值