hdu 3873 Invade the Mars (有限制条件的最短路。。)

hdu3873题目链接

题意:n个点的图。。。每个点可能被若干其他点保护。。。被保护的意思是。。。如果想访问某个点。。那么必须先访问保护该点的所有点。。。问从点1到点n的最小代价。。

思路:。。一开始写了spfa。。。然后一脸懵逼。。。因为我第一次访问某个点的时候无法保证距离是最短的。。。所以还是上dij吧。。。

然后dij写得比较少。。。不是很熟练。。参考了这篇题解参考题解

思路倒是不难想,我在写spfa的时候也是这样想法,然后试图记录路径递归来搞。。。。。然而并不可以2333

也是第一次遇到带限制条件的最短路。。。还是多积累吧。。。

哦对了。。。权值比较大。。。要记得开long long

  1/* ***********************************************
  2Author :111qqz
  3Created Time :2016年07月15日 星期五 00时32分14秒
  4File Name :code/hdu/3873.cpp
  5************************************************ */
  6
  7#include <cstdio>
  8#include <cstring>
  9#include <iostream>
 10#include <algorithm>
 11#include <vector>
 12#include <queue>
 13#include <set>
 14#include <map>
 15#include <string>
 16#include <cmath>
 17#include <cstdlib>
 18#include <ctime>
 19#define fst first
 20#define sec second
 21#define lson l,m,rt<<1
 22#define rson m+1,r,rt<<1|1
 23#define ms(a,x) memset(a,x,sizeof(a))
 24typedef long long LL;
 25#define pi pair < long long ,int >
 26#define MP make_pair
 27
 28using namespace std;
 29const double eps = 1E-8;
 30const int dx4[4]={1,0,0,-1};
 31const int dy4[4]={0,-1,1,0};
 32const int inf = 0x3f3f3f3f;
 33const int N=3E3+7;
 34const int M=7E4+7;
 35int n,m;
 36int cnt;
 37int head[N];
 38int in[N]; //in[i]表示点i被几个点保护。。。
 39vector <int>prec[N];
 40LL d[N];
 41bool vis[N];
 42LL maxt[N];
 43struct Edge
 44{
 45    int v;
 46    LL w;
 47    int nxt;
 48}edge[M];
 49
 50
 51void init()
 52{
 53    ms(head,-1);
 54    ms(in,0);
 55    cnt = 0 ;
 56    for ( int i = 1 ; i <= n ; i++) prec[i].clear();
 57}
 58void addedge( int u,int v,int w)
 59{
 60    edge[cnt].v = v;
 61    edge[cnt].w = w;
 62    edge[cnt].nxt = head[u];
 63    head[u]=cnt;
 64    cnt++;
 65}
 66
 67LL dij( int s)
 68{
 69    priority_queue<pi,vector<pi>,greater<pi> >q;
 70    ms(d,0x3f);
 71    ms(vis,false);
 72    ms(maxt,0);
 73
 74    d[s] = 0 ;
 75    q.push(make_pair(d[s],s));
 76
 77    while (!q.empty())
 78    {
 79	pi cur = q.top();
 80	q.pop();
 81	int u = cur.sec;
 82	if (vis[u]) continue;
 83	vis[u] = true;
 84
 85	int siz = prec[u].size();
 86	for ( int i = 0 ; i < siz ; i++)
 87	{
 88	    int v = prec[u][i];
 89	    in[v]--;
 90	    maxt[v] = max(maxt[v],d[u]);
 91	    if (d[v]!=inf&&!in[v])
 92	    {
 93		d[v] = max(d[v],maxt[v]);
 94		q.push(make_pair(d[v],v));
 95	    }
 96
 97	}
 98	for  ( int i = head[u] ; i != -1 ; i = edge[i].nxt)
 99	{
100	    int v = edge[i].v;
101	    LL w = edge[i].w;
102	    if (d[v]>d[u]+w)
103	    {
104		d[v] = d[u] + w;
105		if (!in[v]) q.push(make_pair(d[v],v));
106	    }
107	}
108    }
109    return d[n];
110
111}
112int main()
113{
114	#ifndef  ONLINE_JUDGE 
115	freopen("code/in.txt","r",stdin);
116  #endif
117
118	int T;
119	cin>>T;
120	while (T--)
121	{
122	    scanf("%d%d",&n,&m);
123
124	    init();
125
126	    for ( int i = 1 ; i <= m ; i++)
127	    {
128		int u,v;
129		LL w;
130		scanf("%d%d%lld",&u,&v,&w);
131		addedge(u,v,w);
132	    }
133	    for ( int i = 1 ; i <= n ; i++)
134	    {
135		int x;
136		scanf("%d",&x);
137		in[i] = x;
138		while (x--)
139		{
140		    int y ;
141		    scanf("%d",&y);
142		    prec[y].push_back(i);
143		}
144	    }
145	    LL ans = dij(1);
146	    printf("%lld\n",ans);
147	}
148
149  #ifndef ONLINE_JUDGE  
150  fclose(stdin);
151  #endif
152    return 0;
153}