poj3635 Full Tank?(spfa+dp)

//package project1;
//可以先不用考慮加油
//只考慮到這個點剩餘油量爲j的最小花費
//那麼我們可以按照最短路的方式來更新
//然後再在這個點統一加油
//一升一升的更新,因爲j-1是最優的,用j-1更新的j也一定是最優的。
//因爲要麼不加油,要麼加的油量肯定大於等於1升
//如果j-1不是最優,那麼少加一升的適合肯定會更新的,
import java.io.*;
import java.util.*;
class Edge{
	int from,to,cap,next;
}
public class Main{
	FastScanner in;
	int n,m;
	int[][] dis;
	int[] cost;
	final int N= 1100;
	final int M=20010,INF=0x3fffffff;
	int cnt;
	int[] head;
	Edge[] edge;
	void init(){
		cnt=0;
		head=new int[N];
		Arrays.fill(head,-1);
		edge=new Edge[M];
		dis=new int[N][110];
	}
	void addedge(int u,int v,int w){
		edge[cnt]=new Edge();
		edge[cnt].from=u;edge[cnt].to=v;edge[cnt].cap=w;
		edge[cnt].next=head[u];head[u]=cnt++;
	}
	void input(){
		in=new FastScanner(System.in);
		init();
		n=in.nextInt();
		m=in.nextInt();
		cost=new int[N];
		
		for(int i=0;i<n;i++){
			cost[i]=in.nextInt();
		}
		for(int i=0;i<m;i++){
			int u,v,w;
			u=in.nextInt();
			v=in.nextInt();
			w=in.nextInt();
			addedge(u,v,w);
			addedge(v,u,w);
		}
		int q=in.nextInt();
		for(int i=0;i<q;i++){
			int c,s,e;
			c=in.nextInt();
			s=in.nextInt();
			e=in.nextInt();
			solve(s,e,c);
		}
	}
	void solve(int s,int e,int c){
		int ans=spfa(s,e,c);
		if(ans==INF)
			System.out.println("impossible");
		else
			System.out.println(ans);

		
	}
	int min(int a,int b){
		if(a>b)return b;
		return a;
	}
	int spfa(int s,int e,int c){
		int[] Q=new int[M];
		int front,rear;
		front=rear=0;
		boolean[] inq=new boolean[N];
		for(int i=0;i<=n;i++)
			for(int j=0;j<=c;j++)
				dis[i][j]=INF;
		for(int j=0;j<=c;j++){
			dis[s][j]=j*cost[s];// 初始化起點
		}
		Q[rear++]=s;
		inq[s]=true;
		while(front!=rear){
			int top=Q[front++];
			if(front==10010)front=0;
			inq[top]=false;
			for(int i=head[top];i!=-1;i=edge[i].next){
				int v=edge[i].to;
				int w=edge[i].cap;
				int flag=0;
				for(int j=w;j<=c;j++){
					if(dis[top][j]<dis[v][j-w]){
						dis[v][j-w]=dis[top][j];
						flag=1;
					}
				}
				if(flag==1){
					for(int k=1;k<=c;k++){
						dis[v][k]=min(dis[v][k],dis[v][k-1]+cost[v]);//解決完別的點解決自己
					}
					if(!inq[v]){
						inq[v]=true;
						Q[rear++]=v;
						if(rear==10010)rear=0;
					}
				}
			}
		}	
		int ans=INF;
		for(int i=0;i<=c;i++)
			ans=min(ans,dis[e][i]);
		return ans;
	}
	public static void main(String args[]){
		new Main().input();
	} 
}
class FastScanner {
    BufferedReader br;
    StringTokenizer st;

    public FastScanner(File f) {
        try {
            br = new BufferedReader(new FileReader(f));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    public FastScanner(InputStream f) {
        br = new BufferedReader(new InputStreamReader(f));
    }

    String next() {
        while (st == null || !st.hasMoreTokens()) {
            String s = null;
            try {
                s = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (s == null)
                return null;
            st = new StringTokenizer(s);
        }
        return st.nextToken();
    }

    boolean hasMoreTokens() {
        while (st == null || !st.hasMoreTokens()) {
            String s = null;
            try {
                s = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (s == null)
                return false;
            st = new StringTokenizer(s);
        }
        return true;
    }

    int nextInt() {
        return Integer.parseInt(next());
    }

    long nextLong() {
        return Long.parseLong(next());
    }

    double nextDouble() {
        return Double.parseDouble(next());
    }
    String nextLine() {
    	
		String str = "";
		try {
			str = br.readLine();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return str;
	}
}

發佈了124 篇原創文章 · 獲贊 46 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章