SPHIWAY - Two "Ways"
no tags
There are N places and M bidirectional way. No two places have more than one direct way. Ana wants to walk from S to T and return to S by a itinerary that satisfy:
- No way can be go twice.
- Length of itinerary is the minimum.
Input
Line 1: 4 integers: N, M, S, T (N <= 104; M <= 105)
Next M line: Line i include 3 integers ui, vi, ci: distance of two places ui and vi is ci. (ci <= 2000000000).
Output
Length of the itinerary if it exists. Else print -1.
Example
Input: 5 7 1 5 1 2 3 1 4 8 2 3 5 2 4 4 3 5 5 4 3 8 4 5 3 Output: 24
题目大意:从S走到T,每条路只能走一次,求最少时间
记得几天前才写过这类题,然后兴高采烈地写了一发,换来的却是无限TLE......现在改过来了,但是因为改的地方还挺多...我也不知道是什么地方让我TLE了....(不得不说SPOJ的界面挺好看的)
建立超级源点和超级汇点,源点与起点相连,容量为2,费用为0,汇点与终点相连,容量为2,费用为0,其他的边正常相连,容量为1,费用为边权。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxm=4e5+7;
const int maxn=1e5+7;
typedef long long ll;
const ll inf=0x3f3f3f3f3f3f3f3f;
struct Node
{
int to;
int capa;
ll cost;
int next;
}edge[maxm*3];
int n,m,s,t,source,sink;
int cnt;
int head[maxn];
int pre[maxn];
int rec[maxn];
ll dis[maxn];
bool vis[maxn];
int in[maxn];
void init()
{
memset(head,-1,sizeof(head));
cnt=0;
return;
}
void add(int u,int v,int capa,ll cost)
{
edge[cnt].to=v;
edge[cnt].capa=capa;
edge[cnt].cost=cost;
edge[cnt].next=head[u];
head[u]=cnt++;
edge[cnt].to=u;
edge[cnt].capa=0;
edge[cnt].cost=-cost;
edge[cnt].next=head[v];
head[v]=cnt++;
return;
}
bool spfa()
{
for(int i=1;i<=n+3;i++)
{
dis[i]=inf;
}
memset(vis,false,sizeof(vis));
memset(pre,-1,sizeof(pre));
memset(rec,-1,sizeof(rec));
memset(in,0,sizeof(in));
dis[source]=0;
vis[source]=true;
queue<int> que;
que.push(source);
while(!que.empty())
{
int node=que.front();
que.pop();
vis[node]=false;
for(int i=head[node];~i;i=edge[i].next)
{
int v=edge[i].to;
if(edge[i].capa>0&&dis[v]>dis[node]+edge[i].cost)
{
dis[v]=dis[node]+edge[i].cost;
rec[v]=i;
pre[v]=node;
if(!vis[v])
{
vis[v]=true;
if(++in[v]>n)
{
return false;
}
que.push(v);
}
}
}
}
return dis[sink]!=inf;
}
void mcmf()
{
int maxflow=0;
ll mincost=0;
while(spfa())
{
int node=sink;
int flow=100000;
while(node!=source)
{
flow=min(flow,edge[rec[node]].capa);
node=pre[node];
}
maxflow+=flow;
node=sink;
while(node!=source)
{
mincost+=flow*edge[rec[node]].cost;
edge[rec[node]].capa-=flow;
edge[rec[node]^1].capa+=flow;
node=pre[node];
}
}
if(maxflow==2) printf("%lld\n",mincost);
else puts("-1");
return;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
//ios::sync_with_stdio(false);
while(~scanf("%d%d%d%d",&n,&m,&s,&t))
{
init();
for(int i=0;i<m;i++)
{
int u,v;
ll w;
scanf("%d%d%lld",&u,&v,&w);
add(u,v,1,w);
add(v,u,1,w);
}
source=0;
sink=n+1;
add(source,s,2,0);
add(t,sink,2,0);
mcmf();
}
return 0;
}