您的位置:首页 > 产品设计 > UI/UE

uestc 方老师抢银行

2015-03-08 22:35 253 查看
参考的大牛的思路和代码

思路: 每次经过一个强连通分量时,都可以走完该分量从而使抢得的钱最多,可以把每个强连通分量缩点,用总的钱数代表该点的值。然后重新遍历新图,遇到网吧可以更新一下结果。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<queue>
#include<algorithm>
#include<map>
#include<iomanip>
#include<climits>
#include<string.h>
#include<cmath>
#include<stdlib.h>
#include<vector>
#include<stack>
#include<set>
using namespace std;
#define INF 1000000007
#define MAXN 300010
#define Mod 1000007
#define N 100007
#define NN 30
#define sigma_size 3
const int maxn = 6e5 + 10;
using namespace std;
typedef long long LL;
const double pi = acos(-1);

vector<int> G[MAXN], G2[MAXN];
int dfn
, lowlink
, instk
, bel
, coin
, iswb
, wb
, coin2
;
int n, m, dfs_clock, scc_cnt, p, k, res;
int u, v;
stack<int> S;

void Tarjan(int u)
{
dfn[u] = lowlink[u] = ++dfs_clock;
S.push(u);
instk[u] = 1;
for (int i = 0; i < G[u].size(); ++i) {
int v = G[u][i];
if (!dfn[v]) {
Tarjan(v);
lowlink[u] = min(lowlink[u], lowlink[v]);
}
else if (instk[v]) {
lowlink[u] = min(lowlink[u], dfn[v]);
}
}
if (lowlink[u] == dfn[u]) {            //找到一个强连通分量
scc_cnt++;                        //强连通分量数目加一
int v;
do {
v = S.top();
S.pop();
if (iswb[v]) wb[scc_cnt] = 1;
instk[v] = 0;
coin2[scc_cnt] += coin[v];
bel[v] = scc_cnt;
if (v == p) p = scc_cnt;
} while (v != u);
}
}

void find_scc()                            //Tarjan求强连通分量
{
for (int i = 1; i <= n; ++i)
if (!dfn[i]) Tarjan(i);
}

void dfs(int u, int sum)                //遍历新建的图
{
sum += coin2[u];
if (wb[u]) res = sum;
for (int i = 0; i < G2[u].size(); ++i)
dfs(G2[u][i], sum);
}

void init()
{
for (int i = 0; i <= n; ++i) {
G[i].clear();
G2[i].clear();
}
while (!S.empty()) S.pop();
dfs_clock = scc_cnt = 0;
memset(instk, 0, sizeof(instk));
memset(dfn, 0, sizeof(dfn));
memset(iswb, 0, sizeof(iswb));
memset(wb, 0, sizeof(wb));
memset(bel, -1, sizeof(bel));
memset(coin2, 0, sizeof(coin2));
memset(lowlink, 0, sizeof(lowlink));
}

void read()
{
for (int i = 0; i < m; ++i) {
scanf("%d%d", &u, &v);
G[u].push_back(v);
}
for (int i = 1; i <= n; ++i)
scanf("%d", &coin[i]);
scanf("%d%d", &p, &k);
for (int i = 0; i < k; ++i) {
scanf("%d", &v);
iswb[v] = 1;
}
}

void rebuild()                                //根据强连通分量重新建图
{
for (int i = 1; i <= n; ++i) {
for (int j = 0; j < G[i].size(); ++j) {
u = bel[i];
v = bel[G[i][j]];
if (u != v)
G2[u].push_back(v);
}
}
res = -1;
dfs(p, 0);
cout << res << endl;
}

void process()
{
init();
read();
find_scc();
rebuild();
}

int main()
{
while (cin >> n >> m)
process();
//system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: