# 【最优高铁环】 分数规划，dfs判负环

7 篇文章 0 订阅
1 篇文章 0 订阅
1 篇文章 0 订阅

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define min(i, j) (i < j ? i : j)
#define max(i, j) (i > j ? i : j)
const int maxn = 5e5 + 60;
const int maxm = 5e5 + 60;

vector<int> G[maxn];
vector<int> l[maxn];

map<string, int> ma;

int orival[maxn];
char saveori[maxn];
char temp[maxn];

double dis[maxn];
int inqcnt[maxn];
int inq[maxn];
int idcnt = 0;
int vis[maxn];
int dfs(int s, double ans)
{
vis[s] = 1;
for (int i = 0; i < G[s].size(); i++)
{
int d = G[s][i];
int len = l[s][i];
//double reallen = (len * 1.0 / ans - 1);
double reallen = len - ans;
if (dis[d] > dis[s] + reallen)
{
dis[d] = dis[s] + reallen;
if (vis[d] || dfs(d, ans))
return 1;
}
}
vis[s] = 0;
return 0;
}

bool func(int s, double ans)
{
for (int i = 1; i <= idcnt; i++)
{
dis[i] = 33333333333.3;
vis[i] = 0;
}
for (int i = 1; i <= idcnt; i++)
{
if (dfs(i, ans)){
// return 1;
}
else
{
return 1;
}
}
return 0;
}

void solve()
{
int n;
cin >> n;
int val = 0;
for (int i = 1; i <= n; i++)
{
val = 0;
scanf("%s", saveori + 1);
int len = strlen(saveori + 1);
int arr = 1;
string s = "", t = "";
while (arr <= len)
{
int temparr = 0;
if (saveori[arr] == ' ')
{
arr++;
continue;
}
while (saveori[arr] != '-' && saveori[arr] != '\n' && arr <= len)
{
temp[temparr++] = saveori[arr++];
}
arr++;
if (temparr)
{
if (temp[0] == 'S')
{
val += 1000;
}
else if (temp[0] == 'G')
{
val += 500;
}
else if (temp[0] == 'D')
{
val += 300;
}
else if (temp[0] == 'T')
{
val += 200;
}
else if (temp[0] == 'K')
{
val += 150;
}
}
temp[temparr] = '\0';
if (s.size() == 0)
{
s = string(temp);
}
t = string(temp);
}
if (!ma.count(t))
{
ma[t] = ++idcnt;
}
if (!ma.count(s))
{
ma[s] = ++idcnt;
}
G[ma[s]].push_back(ma[t]);
l[ma[s]].push_back(val);
}
double r = 0x7fffffff;
double l = 0.00000001;
double ans = -1.0;
while (r - l >= 0.0001)
{
double mid = (r + l) / 2.0;
int res = func(1, mid);
if (res == 0)
{
ans = mid;
l = mid;
}
else
{
r = mid;
}
}
// ans = (l + r) / 2;
printf("%.0f\n", ans);
}

int main()
{
// cout << (1500.0 / 1285 - 1.0) + (1500.0 / 1285 - 1.0) + (850.0 / 1285 - 1.0) << endl;
freopen("in.txt", "r", stdin);
int T;
solve();
}


02-26
07-14 1385
06-27 1480
10-17 992
08-28 98
04-03 401
10-10
02-09
08-28 1341
08-13 36
11-10 1367
03-31 144
11-05 6490
09-16 1125
01-14 4570
11-27 2148
11-27 2195
05-31 3071

### “相关推荐”对你有帮助么？

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

Π鱼星先生

¥2 ¥4 ¥6 ¥10 ¥20

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