前言
9月做的题现在不会了???
越学越拉了属于是。
解析
设
d
i
s
x
dis_x
disx 表示 1-x 的最小距离,那么一条 u->v 的边的边权就是
d
i
s
v
−
d
i
s
u
dis_v-dis_u
disv−disu。
差分约束即可。
挂掉的坑点:只需要考虑1可以到达的点!
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned ll
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define ok debug("OK\n")
inline ll read() {
ll x(0),f(1);char c=getchar();
while(!isdigit(c)) {if(c=='-') f=-1;c=getchar();}
while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return x*f;
}
const int N=2e4+100;
const int mod=1e9+7;
const int inf=1e9+100;
const double eps=1e-9;
bool mem1;
bool Flag=0;
inline ll ksm(ll x,ll k,int mod){
ll res(1);
x%=mod;
while(k){
if(k&1) res=res*x%mod;
x=x*x%mod;
k>>=1;
}
return res;
}
int n,m;
int dp[N];
vector<int>e[N];
int u[N],v[N];
struct node{
int to,nxt,w;
}p[N<<1];
int fi[N],cnt;
inline void addline(int x,int y,int w){
p[++cnt]=(node){y,fi[x],w};fi[x]=cnt;
}
int find(int x){
if(dp[x]!=-1) return dp[x];
if(x==n) return dp[x]=1;
dp[x]=0;
for(int to:e[x]) dp[x]|=find(to);
return dp[x];
}
queue<int>q;
int dis[N],len[N];
bool vis[N];
void spfa(){
memset(dis,0x3f,sizeof(dis));
dis[1]=0;
q.push(1);
while(!q.empty()){
int x=q.front();q.pop();
vis[x]=0;
for(int i=fi[x];~i;i=p[i].nxt){
int to=p[i].to;
if(!dp[to]) continue;
if(dis[to]>dis[x]+p[i].w){
dis[to]=dis[x]+p[i].w;
len[to]=len[x]+1;
if(len[to]>n){
puts("-1");
exit(0);
}
if(!vis[to]){
q.push(to);
vis[to]=1;
}
}
}
}
return;
}
bool mem2;
signed main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
//debug("mem=%.4lf\n",abs(&mem2-&mem1)/1024./1024);
memset(dp,-1,sizeof(dp));
memset(fi,-1,sizeof(fi));cnt=-1;
n=read();m=read();
for(int i=1;i<=m;i++){
u[i]=read();v[i]=read();
e[u[i]].push_back(v[i]);
}
find(1);
for(int i=1;i<=n;i++){
if(dp[i]==-1) dp[i]=0;
}
if(!dp[1]){
puts("-1");return 0;
}
for(int i=1;i<=m;i++){
if(dp[v[i]]==0) continue;
addline(u[i],v[i],9);
addline(v[i],u[i],-1);
}
spfa();
printf("%d %d\n",n,m);
for(int i=1;i<=m;i++){
int res=dis[v[i]]-dis[u[i]];
res=max(res,1);
res=min(res,9);
printf("%d %d %d\n",u[i],v[i],res);
}
return 0;
}
/*
*/