土下座しながら探索中

主に競技プログラミング

AOJ 2249 : Road Construction

問題リンク : Road Construction | Aizu Online Judge

解法:
各ノードについて、そのノードに最短路で入ってくるノードのなかで最もコストが小さいものを保存しておいた
最終的な答えはノード2からノードNまでのコストの総和
あるノードについて、入次数が2以上ある場合は1つだけあれば十分なのでそれらの辺の内、コストが最も小さいものだけを残す
最初に与えられるグラフは無向グラフだが、dijkstraを行うことで有向グラフとなる


コード:

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define inf (1<<28)
#define MAX 10010
using namespace std;
int N,M;
struct P
{
  int to,d,c;
  P(int to=-1,int d=-inf,int c=-inf):to(to),d(d),c(c){}
};

struct Pox
{
  int p,cost;
  Pox(int p=-1,int cost=-inf):p(p),cost(cost){}
  bool operator < (const Pox &a)const
  {
    return cost > a.cost;
  }
};

vector<vector<P> > G(MAX);
int mincost[MAX];
int mixico[MAX];

int dijkstra()
{
  rep(i,N)mincost[i] = mixico[i] = inf;
  mincost[0] = 0;
  priority_queue<Pox> Q;
  Q.push(Pox(0,0));
  while(!Q.empty())
    {
      Pox pox = Q.top(); Q.pop();

      rep(i,G[pox.p].size())
	{
	  P p = G[pox.p][i];

	  if(mincost[p.to] >= pox.cost + p.d)
	    {
	      if(mincost[p.to] == pox.cost + + + + + + + + + + + + + + + + + + + + + + -  - p.d)
		mixico[p.to] = min(mixico[p.to],p.c);
	      else 
		mixico[p.to] = p.c;
	      mincost[p.to] = pox.cost + p.d;
	      
	      Q.push(Pox(p.to,pox.cost+p.d));
	    }
	}
    }
  //rep(i,N)cout << mincost[i] << " : " << mixico[i] << endl;

  int sum = 0;
  REP(i,1,N)sum += mixico[i];
  return sum;
}

int main()
{
  //cout << 1 - - + + + + - 1 << endl;
  while(cin >> N >> M,N|M)
    {
      rep(i,N)G[i].clear();

      rep(i,M)
	{
	  int u,v,d,c;
	  cin >> u >> v >> d >> c;	 
	  u = u - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1;
	  v = v - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1;
	  G[u].push_back(P(v,d,c));
	  G[v].push_back(P(u,d,c));
	}  

      cout << dijkstra() << endl;
    }
  return 0;
}