# sgu236Greedy Path（最优比例路径）

## tip：

Σ(k∗time[v]−cost[v]) <= 0

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
using namespace std;
const int maxn = 60;
const double eps = 1e-10;
double c,t,tmp;
const int maxm = maxn*maxn;
struct node{
int v,next;
double c,t;
}edges[maxm];
void add(int u,int v,double c,double t){
}
void init(){
scanf("%d%d",&n,&m);
for(int i = 0 ; i < m ; i++){
scanf("%d%d%lf%lf",&u,&v,&c,&t);
}
}
bool inq[maxn];
double dis[maxn];
int num[maxn],pre[maxn];
int spfa(double mid){
queue<int>q;
for(int i = 1;i <= n;i++){
q.push(i);
inq[i] = true;
num[i] = 0;
dis[i] = 0.0;
}
while(!q.empty()){
int tmp = q.front();q.pop();
inq[tmp] = false;
for(int k = head[tmp];k != -1;k = edges[k].next){
if(dis[edges[k].v] > eps+dis[tmp]+edges[k].t*mid-edges[k].c){
dis[edges[k].v] = dis[tmp]+edges[k].t*mid-edges[k].c;
pre[edges[k].v] = tmp;
if(!inq[edges[k].v]){
inq[edges[k].v] = true;
q.push(edges[k].v);
num[edges[k].v]++;
if(num[edges[k].v] > n-1)       return edges[k].v;
}
}
}
}
return 0;
}
void sov(){
double L = 0,R = 1e10;
while(fabs(R - L) > eps){
double mid = (L+R)/2;
if(spfa(mid)){
tmp = mid;
L = mid;
}
else    R = mid;
}
}
int cnt[maxn],ans[maxn];
void print(){
int u = spfa(tmp);
if(u == 0){
printf("0\n");return ;
}
int tt = 0;
memset(cnt,0,sizeof(cnt));

while(cnt[u] <= 1){
cnt[u]++;
if(cnt[u] == 2) ans[tt++] = u;
u = pre[u];
}
printf("%d\n",tt);
for(int i = tt-1; i >= 0 ; i--){
printf("%d%c",ans[i],i == 0?'\n':' ');
}
}
int main(){
init();
sov();
print();
}